Ember Data does not recognise ID in JSON response (inheritance-related) - json

I've been trying to figure this out for the past couple of hours and I thought it might be best to ask for some help at this point.
I am creating a new record (e.g., a new ProducerObjectiveOutcome record). The following error is being thrown after my Ember app posts data from a form to my Rails API:
Assertion Failed: Your outcome record was saved to the server, but the response does not have an id and no id has been set client side. Records must have ids. Please update the server response to provide an id in the response or generate the id on the client side either before saving the record or while normalizing the response.
What's strange is that my API is returning a JSON response with an ID (see below).
{
"producer_objective_outcome": {
"id":27,
"type":"ProducerObjectiveOutcome",
"title":"New outcome",
"owner": {
"id":6
}
}
}
As you might already have picked up, ProducerObjectiveOutcome is a subclass of Outcome.
In both my Ember App and Rails API, I have setup ProducerObjectiveOutcome to inherit from Outcome. In my Ember App particular, this is what the model looks like:
// app/models/producer-objective-outcome.js
import Outcome from "./outcome";
export default Outcome.extend({
});
Nothing fancy going on here – I thought it was all pretty straight forward – but for some reason, that error is coming up. I'm hoping one of you marvelous people can help me out with this!
Thanks in advance!

For anyone who is interested, I solved this by changing the name of the root node of the JSON response to outcome instead of it being producer_objective_outcome.
What may have helped in my earlier explanation is that the ProducerObjectiveOutcome record was being created at the following route: producer/objective/:id/outcome/new.
The key part of this URI, as I have figured just out, is the .../outcome/... section. I haven't tested otherwise, but given the conventions in Ember, I suspect that if that URI was .../producer-objective-outcome/... then everything would have been hunky dory.
TL;DR: the names in your JSON payload should match the route.

Related

How to process Vue/Axios Json payload posted data on Yii2

It took me a while to understand this, being that it was a little obvious. I will answer myself, so other can benefit of the answer and ofcourse to see if there's a better way to do this. The problem was based on Axios/Yii2 but I guess this will apply equally to other frontend libraries/frameworks sending data to Yii2.
I needed to post data from a small form made on Vuejs, sending the request Axios to a Action/Controller on Yii2, so data is sent on a simple POST request and the post is getting to the controller, but I was not able to receive the data on the action, $_POST | $post arrives empty (checked using xdebug).
As much as I remember, this had something to do with security. But I already tried by disabling public $enableCsrfValidation, so that was not the problem.
public $enableCsrfValidation = false;
But no matter what, data was not being added to the request/post data inside Yii2.
The following Image, explains the problem you will find there:
The Axisos method that sends the post with test data.
The Yii2 Action stpoed at the place, I should be able to see data.
The capture of the xdebug variables and data for the request.
The capture of Chrome where you can check the payload is sent.
The answer is as I said "kind of obvious", but I could not see that, and I am sure some other devs will probably fall on this.
After searching like crazy and asking everyone, I tried sending the request by using Postman app, yup the best thing I know to test apis.
Dont forgue to add the xdebug cookie to be able to debug your PHP Endpoint.
There I found the first clue «the obvious part», I was not sending data as a form-data, Axios and other libraries, send the data as a raw (application/json) payload.
This means that Yii2 will no be able to find the data inside the post request, yes its there but Yii2 magic will not work, neither you will find this data inside $GLOBALS or in $_POST.
So reading the Yii2 documentation I found that inside request I can use a function that will help me recovering the Raw data, so to do this use the following line:
$raw_data = Yii::$app->request->getRawBody();
Now, that data gets to you as a simple, raw json string, so use the power of PHP to parse it to an object.
$object= json_decode($raw_data );
And finally use the data inside by calling the properties you look for, sent on the pay load:
Json Payload:
{
"msg":"This is my payload",
"id":"11"
}
To use it:
echo $object->{'msg'}; // prints: This is my payload
So that's the way to handle that, now I would like some other points of view to see if there's a better way or cleaner way to do this. Hope it helps.

How to Update Ember Model to Show JSON Search Response

I feel like this answer to this question is trivial, but I am having a difficult time figuring out how to do this the 'Ember way'.
Quick problem background: I am creating a recipe app with Ember frontend and a Rails API backend. I am implementing a search feature to find recipes based on ingredients. I have already configured my Rails API endpoint which sends back the correct records as JSON.
Ember.$.get('/recipes_query', {query: query})
.then(function(reponse) {
// Do something here
});
Now all I need to do is display these. What I am confused about is how to handle the data when it is retrieved (or in other words, how to push these to the store, and then ONLY show the most recently retrieved results). I could push these results to the store and then use a filter to display the correct results, but this seems like an extra step - the JSON response already contains everything I need to display. What is the Ember convention for performing this simple task?
It would be trivial answer if you would use query instead of jQuery.get, so if possible, refactor to:
this.store.query('recipe', {query: query})
.then(records => {
// you have everything you need as records
});

Pentaho HTTP Post using JSON

I'm brand new to Pentaho and I'm trying to do the following workflow:
read a bunch of lines out of a DB
do some transformations
POST them to a REST web service in JSON
I've got the first two figured out using an input step and the Json Output step.
However I have two problems doing the final step:
1) I can't get the JSON formatted how I want. It insists on doing {""=[{...}]} when I just want {...}. This isn't a big deal - I can work around this since I have control over the web service and I could relax the input requirements a bit. (Note: this page http://wiki.pentaho.com/display/EAI/JSON+output gives an example for the output I want by setting no. rows in a block=1 and an empty JSON block name, but it doesn't work as advertised.)
2) This is the critical one. I can't get the data to POST as JSON. It posts as key=value, where the key is the name I specify in the HTTP Post field name (on the 'Fields' tab) and the value is the encoded JSON. I just want to post the JSON as the request body. I've tried googling on this but can't find anyone else doing it, leading me to believe that I'm just approaching this wrong. Any pointers in the right direction?
Edit: I'm comfortable scripting (in Javascript or another language) but when I tried to use XmlHttpRequest in a custom javascript snippet I got an error that XmlHttpRequest is not defined.
Thanks!
This was trivial...just needed to use the REST Client (http://wiki.pentaho.com/display/EAI/Rest+Client) instead of the HTTP Post task. Somehow all my googling didn't discover that, so I'll leave this answer here in case someone else has the same problem as me.
You need to parse the JSON using a Modified JavaScript step. e.g. if the Output Value from the JSON Output is called result and its contents are {"data"=[{...}]}, you should call var plainJSON = JSON.stringify(JSON.parse(result).data[0]) to get the JSON.
In the HTTP Post step, the Request entity field should be plainJSON. Also, don't forget to add a header for Content-Type as application/json (you might have to add that as a constant)

Grails - Do you still need parseRequest for JSON binding to work in controller?

Ok, this is my Nth question regarding this topic, and I'm getting really frustrated with Grails. Please have a quick look on one of my earlier questions for more details.
Among other things, my problem is that sending JSON formatted data to the controller when testing doesn't seem to work. The controller doesn't get null object, but the argument passed is practically empty--the JSON properties don't get set.
Aside from the controller code from the link above, I also tried,
def save() {
def model = new MyModel(request.JSON)
model.save()
}
but it still fails to set properties.
From my Web searches, I read that in older versions, parseRequest must be set to true in UrlMapping.groovy so that request data formatted in XML, JSON, etc. would automatically be parsed and passed as controller method argument. I'm working on Grails 2.3.9, and I'm not sure if it's still necessary to do that.
The time I thought I'd save if I use Grails on this project is being spent on looking for an answer to this seemingly simple task of testing a RESTful Web service.
No since 2.3.0 the parseRequest option doesn't do anything. The request is parsed lazily only when request.XML or request.JSON is accessed or when binding to a command object.

How can I enable GZIP compression of the JSON response entity on Reslet?

I have a Restlet application already working that accepts JSON and returns JSON entity as response.
I'm trying to understand how I can compress the JSON entity that is returned in the response.
I did not find any clear example on how to achieve it.
I think I have to put somewhere on the router chain the Encoder/EncoderService classes, but I really don't understand where and how to use them.
Could anybody help me?
After some testing, I got the answer.
Creating a new filter like this
Filter encoder = new Encoder(getContext(), false, true, new EncoderService(true));
inside the createInboundRoot() method of my own Application class did the trick, the client requests were already containing the gzip header needed.