I am finding it impossible to get the correct formatting for a JSON query to populate an entityreference field on node creation.

From dpm() output, it would seem that the following should work:

{
"title":"Test Node Y",
"type":"element",
"body":{"und":[{"value":"Some text","format":"plain_text"}]},
"field_productentityref":[{"target_id":{"target_id":"[nid:14480]"}}]
}

However, the title and body are created, but not entityreference (field is setup as an autocomplete) is not populated.

I am using Services 3, and since everything else seems to work fine, I assume there is a problem in the entityreference.

Can you please advise on the correct way to do this?

Comments

gmak’s picture

Apologies, the code should be:

{
"title":"Test Node Y",
"type":"element",
"body":{"und":[{"value":"Some text","format":"plain_text"}]},
"field_productentityref":[{"target_id":{"target_id":"[target_id:14480]"}}]
}

(I've tried so many variations, I've managed to confuse myself!)

Damien Tournoud’s picture

{
"title":"Test Node Y",
"type":"element",
"body":{"und":[{"value":"Some text","format":"plain_text"}]},
"field_productentityref":{"und":[{"target_id":14480}]}
}

Why making it more complicated then it needs to be? :)

gmak’s picture

Nice try, but that doesn't work either.

Title and Body are created but not the entityreference field.

odegard’s picture

I'm having the same issue. I'm using services 3 on Drupal 7, trying to create a node with a reference field. I've set it to autocomplete just to be in sync with this issue.

I'm posting this through the firefox poster plugin:

{
  "type":"avvik",
  "title":"My title",
  "field_avvik":{"und":{"0":{"target_id":"[target_id:84]"}}},
  "body":{"und":{"0":{"value":"Some body text"}}}
}

and a new node is created, however, the reference field is empty when I view the node. I've tried a whole lot of different variations like using [] to denote array and not "0" manually... specifying target_type as node... changing the order of things, to no avail.

UPDATE:
Noticed there was a new version some days ago. In the new update, there's no need to specify target_type. Upgrading didn't solve this issue though.

odegard’s picture

I'm trying to dig deeper into this. What I've done is checking the services module for what is received and passed on using watchdog entries. Adding these two watchdogs to line 252 and 253 in _node_resource_create in node_resource.inc shows that $form_state and $node looks fine.

  watchdog('services', 'FORM_STATE <pre>@arguments</pre>', array('@arguments' => print_r($form_state, TRUE)), WATCHDOG_DEBUG);
  watchdog('services', 'NODE <pre>@arguments</pre>', array('@arguments' => print_r($node, TRUE)), WATCHDOG_DEBUG);
  drupal_form_submit($node_type . '_node_form', $form_state, (object)$node);

There are comments in these parts about "drupal_execute", but this is D7 and the code is update to use drupal_form_submit. I think this is the problem. Somehow drupal_form_submit doesn't work right.

I'm still in the process of debugging. I made a PHP-script building up a node and saving it.

error_reporting(E_ALL);
ini_set('display_errors','On');

chdir('/var/www/websites/----------/');

define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$newnode = new stdClass();
$newnode->type = 'bilde';
$newnode->language = LANGUAGE_NONE;
$newnode->title = 'my title';
$newnode->body[$newnode->language][0] = array('value' => 'Some body text');
$newnode->field_avvik[$newnode->language][0] = array('target_id' => '84');
$newnode->name = 'odegard';

print_r(json_encode($newnode));

node_save($newnode);

The node is saved successfully. I then take the json_encoded $newnode-string and run it through poster in firefox, but still the reference is not created. Doing it this way guarantees that I'm working on good data.

I'll read up on drupal_form_submit now.

odegard’s picture

Alright, I've figured how it should work. There's a difference between how the field is populated in a saved node vs. how the field should be populated when creating the node. In the first case, the target_id is the nid of the referenced node. In the latter case, target_id should be on the form "title (nid)" without the quotes.

It seems the problem is a preg_replace in entityreference.module that searches for a number inside two parentheses. In our case using services, we're not actually autocompleting the field... the field doesn't contain the title and (nid), just the nid.

So, I guess the quick fix would be to run the preg_replace if the field is not numeric, say, or check if the field resolves as a nid to a node in the node table. First one is fastest, second one safest.

I could make a patch, just not sure wich approach to go for. Suggestions?

EDIT: actually, this module works as expected... I guess it's rather a question of how we adapt to fields that require data in a certain way. I don't think we can expect module developers to add special cases like for the services module. I'll just adapt my own code to send both title and (nid).

EDIT: this works for me, notice the full title and nid in my custom field:

{
    "type":"bilde",
    "title":"my title2",
    "language":"und",
    "field_avvik":{
        "und":[
            {
                "target_id":"Ludus Occuro Praesent Utrum (69)"
            }
        ]
    },
    "body":{
        "und":[
            {
                "value":"Some body text"
            }
        ]
    },
    "name":"odegard",
}
gmak’s picture

Well, I can see what you have as your format, but this seems to be an over-complicated way of achieving a reference. If I am understanding things, it would mean that i would need to do a lookup on the nid, in order to get the title, and feed this back in to create the entityreference.

If i'm not mistaken, the references module can simply pass in the nid and this will be sufficient. Is there a reason why we can't do the same for the entityreference field?

I'm not familiar enough with the FAPI or the entity stuff to know what is and isn't really going on, but it would seem like a much more streamlined process for Services to simply handle the nid and title, rather than have to feed it in via the JSON.

gmak’s picture

Another thought...

As it appears that it is possible to send just the nid when using the References/Nodereference module, could we simply port the relevant code over to Entityreference?

Again, I'm sorry I'm not clued up enough to root this out, but I'm happy to test anything you can come up with.

yajnin’s picture

Confirmed that this works as well with User References.

Here's how I got it to work:


  // my_user_reference == field name 
  // Marcus == a drupal user name
  // 9 == the related drupal user id

  field_my_user_reference: {

    "und": [{ "target_id" : "Marcus (9)" }]  
       
  }

Not sure if this matters (I suspect not), but when creating this field on the content type, I specified that it use user name to sort. I haven't explored that enough to even know what it does, but at the time I created it I suspected it would allow me to pass the user name as the field variable. I later discovered that the module requires this specific formatting in the string. Conclusion is that the sort setting may not be required. FYI

yajnin’s picture

FYI, for anyone searching regarding the References module, specifically the User Reference field.

I came to Entity Reference from the References module, as I was experiencing problems with Services. Via GET the field in the node object appears to accept (in my case) a Drupal user ID, but POST doesn't seem to work that way.

I thought that a different module might be simpler, and Entity Reference appears quite promising. However, I discovered that it deviates from how core Fields work, in the same way as References – causing the same issue in writing via Services.

So – if you're searching for a solution for References, I'd test this solution on that module too. Or at least I would look closer at the code to see what formatting that module requires.

jbeuckm’s picture

I'm trying to save a node with Entity Reference field via Services. Here is my POST request:

{
  "title":"image layer",
  "body":{
    "und":[
      {"value":""}
    ]
  },
  "type":"layer",
  "language":"und",
  "field_drawing":{
    "und":[
      {"target_id":"drawing (135)"}
    ]
  }
}

Without the Entity Reference field, the node creation is successful. There is definitely a node titled "drawing" with nid=135. This request fails with the message:

{
  "form_errors":{
    "field_drawing][und" : "An illegal choice has been detected. Please contact the site administrator."
  }
}

Is there a way to write a new node or even modify an existing node with an Entity Reference field via Services?

jbeuckm’s picture

SOLVED: I had to set the widget style to autocomplete for this request to set the Entity Reference field successfully.

lance.gliser’s picture

I'm adding an issue relationship to this. Over on https://www.drupal.org/node/2400075, the services maintainers are suggesting we implement a hook that standardizes the input format for fields to what we see on the node object itself. They are keen to do so for the built in core fields, but suggest entity reference should handle its own through the hook mentioned.