6

I have this working in my plugin and all is well with the world:

edit: withAPIData( props => {
            return {
                roles: '/matt-watson/secure-blocks/v1/user-roles/'
            };
        } )( props => {

....

However guidance here suggests that this will no longer be supported going forward: https://github.com/WordPress/gutenberg/issues/7390#issuecomment-398667802

So I have managed to work that into the solution:

const DEFAULT_STATE = {
userRoles: {},
};

const actions = {
    setUserRoles( userRoles ) {
        return {
            type: 'SET_USER_ROLES',
            userRoles,
        };
    },

    fetchFromAPI( path ) {
        return {
            type: 'FETCH_FROM_API',
            path,
        };
    },
};

registerStore( 'matt-watson/secure-block', {
    reducer( state = DEFAULT_STATE, action ) {

        switch ( action.type ) {
            case 'SET_USER_ROLES':
                return {
                    ...state,
                    userRoles: action.userRoles,
                };
        }

        return state;
    },

    actions,

    selectors: {
        getUserRoles( state ) {
            const { userRoles } = state;
            return userRoles;
        },
    },

    controls: {
        FETCH_FROM_API( action ) {
            return apiFetch( { path: action.path } );
        },
    },

    resolvers: {
        * getUserRoles( state ) {
            const path = '/matt-watson/secure-blocks/v1/user-roles/';
            const userRoles = yield actions.fetchFromAPI( path );
            return actions.setUserRoles( userRoles );
        },
    }

    ,
    } );

....

edit: withSelect( ( select ) => {
                                return {
                                    roles: select('matt-watson/secure-block').getUserRoles(),
                                };
                            } )( props => {

....

Now the issue is that the 'controls' section never fires. In the documentation it says that this is an opt-in component, and I need to enable it via the use command: https://github.com/WordPress/gutenberg/tree/master/packages/data#controls

When I try this, use is undefined.

So my question is this. As withAPIData did everything I needed in a very quick and easy way, is there an alternative 'drop-in' bit of code I can use, or do I need to progress with the store that I am registering? If so, what am I doing wrong?

Any help appreciated. Thank you.

  • I would note that ... is also valid javascript, as the object spread operator – Tom J Nowell Aug 14 '18 at 15:45
  • I would also guess that you need to define some packages as requirements via npm for the parts that require use – Tom J Nowell Aug 14 '18 at 15:51
  • Thanks @TomJNowell, yeah good point on the ... I'll have to come up with another way to add snippets. I'll have another look into use. If I fix this I'll write a glorious blog post! – Matt Watson Aug 14 '18 at 18:29
  • Hmm, no luck importing @wordpress/data, I can get the use functions, but not a lot happens. – Matt Watson Aug 14 '18 at 19:59
3

I've cracked it!

const actions = {
    setUserRoles( userRoles ) {
        return {
            type: 'SET_USER_ROLES',
            userRoles,
        };
    },

    receiveUserRoles( path ) {
        return {
            type: 'RECEIVE_USER_ROLES',
            path,
        };
    },
};

const store = registerStore( 'matt-watson/secure-block', {
    reducer( state = { userRoles: {} }, action ) {

        switch ( action.type ) {
            case 'SET_USER_ROLES':
                return {
                    ...state,
                    userRoles: action.userRoles,
                };
            case 'RECEIVE_USER_ROLES':
                return action.userRoles;
        }

        return state;
    },

    actions,

    selectors: {
        receiveUserRoles( state ) {
            const { userRoles } = state;
            return userRoles;
        },
    },

    resolvers: {
        * receiveUserRoles( state ) {
            const userRoles = apiFetch( { path: '/matt-watson/secure-blocks/v1/user-roles/' } )
                .then( userRoles => {
                    return actions.setUserRoles( userRoles );
                } )
            yield userRoles;
        },
    },

} );

This sets the state of the userRoles and returns the userRoles once resolved.

You can then access this like so:

....

edit: withSelect( ( select ) => {
                return {
                    roles: select('matt-watson/secure-block').receiveUserRoles(),
                };
            } )( props => {

....

1

It's worth noting that the answer above is out of date. The data store should now look like this:

const actions = {
    setUserRoles( userRoles ) {
        return {
            type: 'SET_USER_ROLES',
            userRoles,
        };
    },
    receiveUserRoles( path ) {
        return {
            type: 'RECEIVE_USER_ROLES',
            path,
        };
    },
};

const store = registerStore( 'matt-watson/secure-block', {
    reducer( state = { userRoles: {} }, action ) {

        switch ( action.type ) {
            case 'SET_USER_ROLES':
                return {
                    ...state,
                    userRoles: action.userRoles,
                };
        }

        return state;
    },

    actions,

    selectors: {
        receiveUserRoles( state ) {
            const { userRoles } = state;
            return userRoles;
        },
    },

    controls: {
        RECEIVE_USER_ROLES( action ) {
            return apiFetch( { path: action.path } );
        },
    },

    resolvers: {
        * receiveUserRoles( state ) {
            const userRoles = yield actions.receiveUserRoles( '/matt-watson/secure-blocks/v1/user-roles/' );
            return actions.setUserRoles( userRoles );
        },
    },
} );

I've updated my tutorial: https://mwatson.co.uk/working-with-gutenberg-and-the-wordpress-rest-api/

  • Thank you! But you could have edited your answer instead of writing a new one. – Fabian von Ellerts Jan 31 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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