2

For a wordpress challenge I need to make a dropdown with all categories and I need to use apifetch So I have this :

/**
 * Retrieves the translation of text.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
 */
import { __ } from '@wordpress/i18n';

/**
 * React hook that is used to mark the block wrapper element.
 * It provides all the necessary props like the class name.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
 */
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, SelectControl } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import React, { useState, useEffect } from "react";
import { addQueryArgs } from '@wordpress/url';

/**
 * Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
 * Those files can contain any CSS code that gets applied to the editor.
 *
 * @see https://www.npmjs.com/package/@wordpress/scripts#using-css
 */
import './editor.scss';




/**
 * The edit function describes the structure of your block in the context of the
 * editor. This represents what the editor will render when the block is used.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
 *
 * @return {Element} Element to render.
 */
export default function Edit() {

  const [categories, setCategories] = useState([]);

  const [chosenCategory, setChosenCategory] = useState(0);

  const [posts, setPosts] = useState([]);

  useEffect(() => {

    async function fetchCategories() {

      const queryParams = { _fields: ['name', 'id'] };

      try {

        const response = await apiFetch({ path: addQueryArgs('/wp/v2/categories', queryParams) });

        setCategories(response);
        console.log(categories); 

      } catch (error) {

        console.log(error);

      }

    }

    fetchCategories();

  }, []);
  

  return (
    <>
      <InspectorControls>
        <PanelBody title={__('Settings', 'rw-filter-categories')}>
          <SelectControl
            label="Choose Category"
            value={chosenCategory}
            options={categories}
            onChange={(category) => setChosenCategory(category)}
          />
        </PanelBody>
      </InspectorControls>
      <p {...useBlockProps()}>
        {__(

          "test",
          'rw-filter-categories'
        )}
      </p>
    </>
  );

}

but I see now that the dropdown is still empty. Can someone explain why that happens and how to solve this ?

I see that the api returns this :

Array [ {…} ]
​
0: Object { label: "Niet gecategoriseerd", value: 1 }

I do not see any errors in the console but I see that categories is a empty array

1 Answer 1

0

I'd guess you may have figured this out by now. Here’s my answer anyway.

You say the API returns an array whose object items have label and value properties but if I try that same request I get an array whose object items have name and id properties (as you would expect when you specify _fields: [ 'name', 'id' ]. That won’t work for passing to SelectControl as options. You'd need to map the array to create one with the properties required (label and value).

setCategories( response.map( ({ name: label, id: value }) => ({ label, value }) ) );

I do not see any errors in the console but I see that categories is a empty array

If you log categories just after you setCategories it’s going to be stale (the value it was already). Setting state in React is not synchronous and categories won’t have the latest value until the component renders again (as setting state queues it to do).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.