I have a custom gutenberg block which is dynamically fetching custom post data via wp-json on edit. How do I persevere the data on save for the fronted?

here is my custom component (preview.js) which I include in edit method

const { __ } = wp.i18n
const { Component } = wp.element

export default class Preview extends Component {

    state = {
        teachers: false,
    }

    getTeachers = () => {
        const { location } = this.props.attributes

        fetch( `/wp-json/wp/v2/teachers` )
            .then( response => response.json() )
            .then( teachers => {
                this.setState( { teachers: teachers } )
            } )
    }

    componentWillMount() {
        this.getTeachers()
    }

    componentDidUpdate(lastProps, lastStates) {
        if( lastProps.attributes.productID != this.props.attributes.productID ) {
            this.getTeachers()
        }
    }

    render() {
        const { teachers } = this.state

        let wrapper;
        if (teachers) {
            wrapper = teachers.map(function (teacher) {
                return (
                    <div className="wp-block-profiles__element" key={teacher.id}>
                        <div className="wp-block-profiles__image-container">
                            <img className="wp-block-profiles__image" src={ teacher.profile_image.url } alt={ teacher.profile_image.alt } />
                        </div>

                        <h4>{teacher.first_name} {teacher.last_name}</h4>
                    </div>
                )
            })
        }

        return (
            !! teachers ? (
                <div className="wp-block-profiles">
                    {wrapper}
                </div>
            ) : (
                <p className="profile-block-message">{ __( 'Loading Profiles...', 'block-profiles' ) }</p>
            )
        )
    }
}

and here is where I register my custom block

//  Import CSS.
import './style.scss'
import './editor.scss'
import Inspector from './inspect'
import Preview from './preview'

const { __ } = wp.i18n; // Import __() from wp.i18n
const {
    registerBlockType,
} = wp.blocks

const { Fragment } = wp.element

/*
 * @param  {string}   name     Block name.
 * @param  {Object}   settings Block settings.
 * @return {?WPBlock}          The block, if it has been successfully
 *                             registered; otherwise `undefined`.
 */
registerBlockType( 'cgb/profiles-cgb-block', {
    // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
    title: __( 'Profiles' ), // Block title.
    icon: 'shield', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
    category: 'custom-category', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
    keywords: [
        __( 'Profiles' ),
        __( 'CGB' ),
        __( 'teachers'),
    ],
    attributes: {
        teachers: {
            type: 'array',
            default: [],
        },
        locations: {
            type: 'array',
            default: [],
        },
        levels: {
            type: 'array',
            default: [],
        }
    },
    edit: ( props ) => {
        const { attributes, setAttributes, posts } = props
        const { locations, levels, teachers } = attributes

        return [
            <Fragment>
                <Inspector { ...{ attributes, setAttributes } } />

                { !! locations ? (
                    <Preview { ...{ teachers, levels, attributes } } />
                ) : (
                    <p class="profiles-block-message">{ __( 'Please select at least Location to render profiles', 'cgb/block-profiles' ) }</p>
                ) }
            </Fragment>
        ]
    },
    save: ( props ) => {
        return null
    },
} );

In this case everything is getting saved in the editor but nothing shows in frontend

  • Your save function is empty. Did you use PHP to render the save on the front end? If yes, kindly share that code as well – Ashiquzzaman Kiron Oct 2 at 8:03
  • Hi, thanks for feedback I did not used any php method in this case, I tought it can be rendered in the same way as in backend – fefe Oct 5 at 12:11

What you are building is called 'Dynamic Block' and Your block will not work because you haven't added the front end code ( which is the PHP part for dynamic block ). See this official block code there's PHP part as well to save the block and work on the front end.

Here's the official explanation -

Because it is a dynamic block it also needs a server component. The rendering can be added using the render_callback property when using the register_block_type function.

Although you can use ServerSideRender component but it's not recommended.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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