Can I use normal (rails default) JSON response on Ember Data? - json

I'm working on a project using Ember/Ember-Data and there is a related/already existing service which is provide API with JSON response.
My project must interact with that service, but the response from that API is someting like below:
{ "id": 39402, "name": "My Name" }
or
[ {"id": 38492, "name": "Other Name" } ]
there is no person: or persons: that is required by Ember-Data compatable response.
How can I using this response on Ember-Data without change on the service or without build API gateway?

Ember-Data uses DS.RestAdapter, which in turn uses DS.RESTSerializer which extends from DS.JSONSerializer for serializing, extracting and massaging data that comes in from the server.
Since in your case you already have the data in your payload, all you need to do for reading the data is override extract method in the JSONSerializer which is actually quite simple.
If you are using ember-cli (which you should :)), your person.js file located inside your app/serializers directory would look as follows.
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
extract: function(store, primaryType, payload) {
return payload;
}
});
If you are not using ember-cli, you can do the following:
App.PersonSerializer = DS.JSONSerializer.extend({
extract: function(store, primaryType, payload) {
return payload;
}
});

Related

Can I create record in Ember without the record name

My Backend Rails API consumes POST requests in the form of
{
"name": "Mark White",
"email" : "mark#xyz.com"
}
Have tried this in Postman and this creates a record successfully.
In my ember frontend, Im using the following code to create a new record, from a form input:
app/routes/addUser.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
addUser(){
let formData = {
"name": this.controller.get('name'),
"email": this.controller.get('email')
};
let newUser = this.store.createRecord('user',formData);
newUser.save();
}
}
});
which generates the request as
{
"user": {
"name": "Mark White",
"email" : "mark#xyz.com"
}
}
which my backend is not prepared to handle and throws an error.
Any way I can quickly conform to the json format that works for me in Postman.
When the question is along the lines with the "How can I change my payload to server for it to be in a certain format?" then you should have a look at customizing a serializer.
But it looks like for solving your problem you might wanna take the standard JSON Serializer; in your app/serializers/application.js just type the following:
import JSONSerializer from '#ember-data/serializer/json';
export default class ApplicationSerializer extends JSONSerializer {
// ...
}
Note that it's for the Ember.js v4, according to your example you're using a bit older version so just adjust the syntax accordingly.

How do I extract JSON data from a raw.github URL and store it in a variable?

Let's say that I have a JSON file called data.json in Github. I can view it in raw in a Github URL like this: https://raw.githubusercontent.com/data.json (This is a hypothetical URL. It's not real)
And let's say that URL contains JSON data like this:
"users_1": [
{
"id": 1234,
"name": "Bob"
},
{
"id": 5678,
"name": "Alice"
}
]
How do I extract the whole JSON data from that URL and store it in a variable in a Cypress test? I know that Cypress doesn't really use Promises, so I'm finding it difficult to implement this. So far I got this in Typescript:
let users; // I want this variable to store JSON data from the URL
const dataUrl = "https://raw.githubusercontent.com/data.json";
cy.request(dataUrl).then((response) => {
users = JSON.parse(response); // This errors out because response is type Cypress.Response<any>
})
I'm planning to do something like this in the future for my project when migrating from Protractor to Cypress. I have a Protractor test that extracts JSON data from a Github file and stores it a variable by using a Promise. I want to do the same kind of task with Cypress.
I think you should use response.body, and it should have been serialized.
A request body to be sent in the request. Cypress sets the Accepts request header and serializes the response body by the encoding option. (https://docs.cypress.io/api/commands/request#Usage)

How to handle json in angular4

When I work with a partner to write a website, the backend returns the json format as follows. My front end uses angular4 but I don't know how to use angular4 to process the following json format data. It is a bit worse and there is no json.parse method.
{
"pageNum":1,
"pageSize":4,
"size":1,
"startRow":1,
"endRow":1,
"total":1,
"pages":1,
"list":[
{
"owner":"aa",
"zh_name":"武世伟:广佛06.19-24搭乘ID(正确)",
"push_status":1,
"business":1,
"create_time":1514256602000,
"coupon_status":1,
"monitor_status":1,
"model_status":3,
"message_status":1,
"monitor_end_time":1514256602000,
"random_group":1,
"name":"p_pm_passenger_taxi_20171226105028119",
"calc_way":1,
"monitor_start_time":1514256602000,
"id":11,
"model_num":8837
}
],
"prePage":0,
"nextPage":0,
"isFirstPage":true,
"isLastPage":true,
"hasPreviousPage":false,
"hasNextPage":false,
"navigatePages":8,
"navigatepageNums":[
1
],
"navigateFirstPage":1,
"navigateLastPage":1,
"status":200,//状态200正常,400 错误
"firstPage":1,
"lastPage":1
}
Angular indeed provides you with a JSON.parse()-method which actually derives from JavaScript. You can convert your server response json into an object.
// in your component
private object;
Then you can access the content. For example:
// call this method after having received your json
private show(data: any): void {
this.object = JSON.parse(data);
console.log(this.object.pageNum);
console.log(this.object.total);
console.log(this.object.list[0].zh_name);
}

TypeScript / Angular 2 creating a dynamic object deserializer

So I am coming from a background of C# where I can do things in a dynamic and reflective way and I am trying to apply that to a TypeScript class I am working on writing.
Some background, I am converting an application to a web app and the backend developer doesn't want to change the backend at all to accommodate Json very well. So he is going to be sending me back Json that looks like so:
{
Columns: [
{
"ColumnName": "ClientPK",
"Label": "Client",
"DataType": "int",
"Length": 0,
"AllowNull": true,
"Format": "",
"IsReadOnly": true,
"IsDateOnly": null
}
],
Rows:[
0
]
}
I am looking to write an Angular class that extends Response that will have a special method called JsonMinimal which will understand this data and return an object for me.
import { Response } from "#angular/http";
export class ServerSource
{
SourceName: string;
MoreItems: boolean;
Error: string;
ExtendedProperties: ExtendedProperty[];
Columns: Column[];
}
export class ServerSourceResponse extends Response
{
JsonMinimal() : any
{
return null; //Something that will be a blank any type that when returned I can perform `object as FinalObject` syntax
}
}
I know StackOverflow isn't for asking for complete solutions to problems so I am only asking what is one example taking this example data and creating a dynamic response that TypeScript isn't going to yell at me for. I don't know what to do here, this developer has thousands of server-side methods and all of them return strings, in the form of a JSON or XML output. I am basically looking for a way to take his column data and combine it with the proper row data and then have a bigger object that holds a bunch of these combined object.
A usage case here after that data has been mapped to a basic object would be something like this.
Example:
var data = result.JsonMinimal() as LoginResponse; <-- Which will map to this object correctly if all the data is there in a base object.
var pk = data.ClientPK.Value;
I'm not exactly sure I understand, but you may want to try a simple approach first. Angular's http get method returns an observable that can automatically map the response to an object or an array of objects. It is also powerful enough to perform some custom mapping/transformation. You may want to look at that first.
Here is an example:
getProducts(): Observable<IProduct[]> {
return this._http.get(this._productUrl)
.map((response: Response) => <IProduct[]> response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
Here I'm mapping a json response to an array of Product objects I've defined with an IProduct interface. Since this is just a "lambda" type function, I could add any amount of code here to transform data.

How can I serialize a Simple array payload in ember?

I am pretty new to Ember. I have a service which returns a simple array like
[
"abc",
"bcd",
"cde",
"def",
"efg"
]
My model is somewhat like this
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
value: attr()
});
In the serializer(I am trying with RESTSerializer), I want this data to be sent back to route.js where the service call is made. The service call is to an API which I am not allowed to change in any way.
I tried a lot of ways that might be stupid and googled a lot. Sadly I could not find a solution though I believe it may not be too tough.
I got the payload in serializer as pasted above and was able to log the response. From there what is to be returned and what serializer is apt is my current problem. Kindly ask me if any further details are required to figure this out. I am not posting much so that I can keep it simple and understandable. Any help is appreciated.
You may not want to use Ember Data. However, you can by implementing normalizeResponse in your Serializer.
For example, if your model name is "account":
export default DS.RESTSerializer.extend({
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
let newPayload= {
accounts: [{
value: payload
}]
};
return this._super(store, primaryModelClass, newPayload, id, requestType);
}
});