2

I have been trying to create a Gutenberg block that displays a list of categories as checkboxes on my WordPress edit pages, and then displays on the frontend page a list of posts that are linked to the selected categories.

I have successfully added the checkboxes for the edit pages. When I choose the categories, update, then refresh the page, they stay the way I previously left them.

But I can't seem to figure out how I can do an API call to get a list of posts linked to the categories I've selected.

This is my edit code and attributes:

let globalCategories = [];
let globalPosts = [];

const data = wp.apiFetch({ path: '/wp/v2/categories' })
   .then(( obj ) => {
       globalCategories.push(obj.map(o => {
           return o;
       }));

       return globalCategories;
   });

registerBlockType( 'mdlr/multi-category-list', {
   title: __( 'Digiminster: Multi Category List' ),
   icon: 'lock',
   category: 'common',
   attributes: {
       checkedArray: { type: 'array' },
       postsArray: { type: 'array' }
   },
   edit(props) {
        console.log("checkedArray: ", props.attributes.checkedArray);
       if(props.attributes.checkedArray === undefined) {
           props.attributes.checkedArray = globalCategories[0];
       }

       function updateContent(event, index) {
           props.setAttributes({
               checkedArray: props.attributes.checkedArray.map((o, i) => {
                   if (index === i) {
                       o.checked = event.target.checked;
                   }

                   return o;
               })
           });
       }

       return props.attributes.checkedArray.map((c, i) => (
           <div>
               <input
                   type="checkbox"
                   checked={c.checked}
                   onChange={e => updateContent(e, i)}
               />
               <label>{c.name}</label>
           </div>
       ));
   },
   ...

And this is my save code:

save: class extends wp.element.Component {
    constructor(props) {
        super(props);
        this.state = props.attributes;
    }

    updateContent(contentData) {
        console.log("Hello", globalPosts);
        this.setState({ postsArray: globalPosts });
        console.log(this.state.postsArray); // <- Returns undefined
    }

    render() {
        let checkedArray = this.state.checkedArray;

        if (checkedArray !== undefined) {
            let categoryIds = checkedArray.filter(c => c.checked === true).map(c => c.id).join();

            if (categoryIds !== '') {
                wp.apiFetch({ path: '/wp/v2/posts?categories=' + categoryIds })
                    .then(( obj ) => {
                        globalPosts = obj.map(o => o);
                        console.log("Global posts", globalPosts);
                        return globalPosts;
                    });
            }       
        }

        let postsLoadingTimer = setInterval(() => {
            if (globalPosts !== undefined) {
                this.updateContent(globalPosts);
                clearInterval(postsLoadingTimer);
            }
        });

        return (
            <div>helloooooo</div>
        );
    }
}

I want to be able to get the this.state.postsArray, loop through it and display my posts but this.setState doesn't seem to be working and is making this.state.postsArray return 'undefined'.

I've written the timer thinking that it might help me update the content with this.setState.

My main goal is to display a list of posts based on selected categories.

Joshua Waheed
  • 277
  • 4
  • 16

0 Answers0