4

I am trying to add custom post data( post meta data) through wordpress API but I am getting difficulty while updating/adding custom post data. below is the code that am using.

Code written in function.php

    add_action( 'rest_api_init', 'create_api_posts_meta_field' );

function create_api_posts_meta_field() {

 // register_rest_field ( 'name-of-post-type', 'name-of-field-to-return', array-of-callbacks-and-schema() )
 register_rest_field( 'experience', 'subtitle', array(
 'get_callback' => 'get_post_meta_for_api',
 'update_callback'   => 'update_post_meta_for_exp',
 'schema' => null,
 )
 );
}


function update_post_meta_for_exp($object, $meta_value ) {
                $havemetafield  = get_post_meta($object['id'], 'experience', false);
                if ($havemetafield) {
                    $ret = update_post_meta($object['id'], 'subtitle', $meta_value );
                    return true;
                } else {
                    $ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
                    return true;
                }
            }

function get_post_meta_for_api( $object ) {
 //get the id of the post object array
 $post_id = $object['id'];

 //return the post meta
 return get_post_meta( $post_id )["Subtitle"][0];
}

 function create_api_posts_meta_field_time() {



// register_rest_field ( 'name-of-post-type', 'name-of-field-to-return', array-of-callbacks-and-schema() )
 register_rest_field( 'experience', 'timing_of_experience', array(
 'get_callback' => 'get_post_meta_for_api_time',
 'update_callback'   => function($meta_value ) {
                $havemetafield  = get_post_meta(1, 'experience', false);
                if ($havemetafield) {
                    $ret = update_post_meta(1, 'timing_of_experience', $meta_value );
                    return true;
                } else {
                    $ret = add_post_meta( 1, 'timing_of_experience', $meta_value ,true );
                    return true;
                }
            },
 'schema' => null,
 )
 );
}

function get_post_meta_for_api_time( $object ) {
 //get the id of the post object array
 $post_id = $object['id'];

 //return the post meta
 return get_post_meta( $post_id )["timing_of_experience"][0];
}

JS file included in page I am working on

var quickAddExperience = document.querySelector("#quick-add-experience");

  if (quickAddExperience) {

        quickAddExperience.addEventListener("click",function() {

                var ourPostData = {
                    'title'                  : document.getElementById('title').value,
                    'content'                : document.getElementById('content').value,
                    'subtitle'               : document.getElementById('company_name').value,
                    'timing_of_experience'   : document.getElementById('time_period').value,
                    'status'                 : 'publish'
                }

                console.log(ourPostData);
                var createPost = new XMLHttpRequest();
                createPost.open("POST", magicalData.siteURL + "/wp-json/wp/v2/experience-api");
                createPost.setRequestHeader("X-WP-Nonce", magicalData.nonce);
                createPost.setRequestHeader("Content-Type","application/json;charset=UTF-8");
                createPost.send(JSON.stringify(ourPostData));
                createPost.onreadystatechange = function(){
                    if (createPost.readystate == 4) {
                        if (createPost.status == 201) {
                                document.querySelector('.data-api-post-1 [name="title"]').value ='';
                                document.querySelector('.data-api-post-1 [name="content"]').value ='';
                                document.querySelector('.data-api-post-1 [name="company_name"]').value ='';
                                document.querySelector('.data-api-post-1 [name="time_period"]').value ='';
                        }else{
                            alert("Error - try again");
                        }
                    }
                }


        });
    }

This code is working for default field means new post is created but only title and content is there.

Edit: When I tried to debug the then came to know that update_callback code is not executing but get_callback is executing.

4
  • where do you not retrieve the values ? the minimum of debugging is to display the content of the variables that doesn't contain the expected value.
    – mmm
    Commented Jan 11, 2018 at 18:31
  • sorry doesn't understand what you are asking Commented Jan 12, 2018 at 2:50
  • Can you boil it down to the bare minimum to reproduce the problem? There's a lot extra code in there that makes it harder to read.
    – janh
    Commented Jan 15, 2018 at 14:49
  • @janh it's minimum code . Commented Jan 16, 2018 at 4:58

2 Answers 2

2
+50

I just ran a test with your code and in my opinion, this is not working because you have an error in the get_callback function.

First time it will try to get the subtitle( or the timing_of_experience) but it will trigger an error because it doesn't exists in the first place and this error will block the registration of the update_callback.

So, the problem is that in the get_callback the Subtitle key has a capital S and this is not the way it is saved.

Second, you should respect the general rule of validating data and check if the value exists before trying to access it. Like this:

function get_post_meta_for_api( $object ) {
    //get the id of the post object array
    $post_id = $object['id'];

    $meta = get_post_meta( $post_id );

    if ( isset( $meta['subtitle' ] ) && isset( $meta['subtitle' ][0] ) ) {
        //return the post meta
        return $meta['subtitle' ][0];
    }

    // meta not found
    return false;
}

Like I said, I ran a test, replacing your experience post type with post and it is working.

Bonus tips, you should try to organize your code better since it is hard to read with this indentation and functions order. also, the for the update_callback a simple return true is enough.

function update_post_meta_for_exp($object, $meta_value ) {
    $havemetafield  = get_post_meta($object['id'], 'experience', false);
    if ($havemetafield) {
        $ret = update_post_meta($object['id'], 'subtitle', $meta_value );
    } else {
        $ret = add_post_meta( $object['id'], 'subtitle', $meta_value ,true );
    }
    return true;
}
0
1

You can write custom post data using below code. I write custom post type "ad_portfolio" categories and featured image in WordPress API using below code. hope it helps. Thanks

    function prepare_rest($data, $post, $request){
    $_data = $data->data;

    $thumbnail_id = get_post_thumbnail_id( $post->ID );
    $featured_media_url = wp_get_attachment_image_src( $thumbnail_id, 'large' );

    $post_categories = wp_get_post_terms( $post->ID, 'ad_portfolios' , array("fields" => "all") );
    $cats = array();

    foreach($post_categories as $cat){
        $cats[] = ['slug' => $cat->slug, 'name' => $cat->name ];
    }

    $_data['featured_media_url'] = $featured_media_url[0];
    $_data['portfolio_cats'] = $cats;
    $data->data = $_data;

    return $data;
}
add_filter('rest_prepare_ad_portfolio', 'prepare_rest', 10, 3);
//post type is "ad_portfolio"
1
  • Thanks for reply but it doesn't look the solution I asked for, will you please explain how it will work and my code is not working ? Commented Jan 17, 2018 at 5:04

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.