Returning record(s) after store pushPayload call - ember.js

Is there a better way to return the record(s) after DS.Store#pushPayload is called? This is what I'm doing...
var payload = { id: 1, title: "Example" }
store.pushPayload('post', payload);
return store.getById('post', payload.id);
But, with regular DS.Store#push you get the inserted record returned. The only difference between the two, from what I can tell, is that DS.Store#pushPayload serializes the payload data with the correct serializers.

DS.Store#pushPayload is able to take an array of items, not just one, and may contain side-loaded data. It processes a full payload and expects root keys in the payload:
{
"posts": [{
"id": 1,
"title": "title",
"comments": [1]
}],
"comments": [
//.. and so on ...
]
}
DS.Store#push expects a single record which has been normalized and contains no side loaded data (notice there is no root key):
{
"id": 1,
"title": "title",
"comments": [1]
}
For this reason, it makes sense for push to return the record, but for pushPayload to return nothing.
When you use pushPayload, a second lookup of store.find('post', 1) (or store.getById('post', 1)) is the way to go, I don't believe there is a better way.

As of this PR pushPayload can now return an array of all the records pushed into the store, once the 'ds-pushpayload-return' feature flag has been enabled.
At the moment, this feature isn't available in a standard or beta release-- you'll have to use
"ember-data": "emberjs/data#master",
(i.e. Canary) in your package.json in order to access it. I'm not sure when the feature will be generally available.

Related

How to add map to map array in AWS DynamoDB only when id is not existed?

Here is my DynamoDB structure.
{"books": [
{
"name": "Hello World 1",
"id": "1234"
},
{
"name": "Hello World 2",
"id": "5678"
}
]}
I want to set ConditionExpression to check whether id existed before adding new items to books array. Here is my ConditionExpression. I am using API gateway to access DynamoDB.
"ConditionExpression": "NOT contains(#lu.books.id,:id)",
"ExpressionAttributeValues": {":id": {
"S": "$input.path('$.id')"
}
}
Result when I test the API: no matter id existed or not, success to add items to array.
Any suggestion on how to do it? Thanks!
Unfortunately, you can't. However, there is a workaround.
Store the books in separate rows. For example
PK SK
BOOK_LU#<ID> BOOK_NAME#<book name>#BOOK_ID#<BOOK_ID>
Now you can use the 'if_not_exists' conditional expression
"ConditionExpression": "if_not_exists(id, :id)'",
"ExpressionAttributeValues": {":id": {
"S": "$input.path('$.id')"
}
}
The con is if you were previously fetching the list as part of another object you will have to change that.
The pro is that now you can easily work with the books + you won't hit the max row size limits if the books became too many.

How to convert array of object(hasMany relationship data) to array of id?

I wanted to get data and show it in UI. Here's how i write to get the "movies" data.
let movies= yield this.store.findAll('movie');
And I log the "movies". As the picture below shows that there's no data for "photos".
Here's the network:
I'm getting data back from hasura like this:
{
"data": {
"movies": [
{
"id": "584db434-5caa-475e-b3ec-e98e742f0030",
"movieid": "abc123",
"description": "Penquins dancing in antactica",
"photos": [
{
"id": "c4d2833a-4896-42b0-ae8b-0ab9fe71d1d4"
},
{
"id": "e04697e3-21fe-4f0e-8012-443f26293340"
}
]
}
]
}
}
But Ember.js can't read and render the relationship data (photos). Is it the "photos" data should be like this?
"photos": [c4d2833a-4896-42b0-ae8b-0ab9fe71d1d4, e04697e3-21fe-4f0e-8012-443f26293340]
How can I convert it in Ember? or in Hasura?
Thanks for updating your question!
Since you're using ember-data, you'll need a custom adapter and serializer to form your data into the format that ember-data is expecting (since there are infinite numbers of ways APIs decide how to structure data).
More information on that can be found here:
https://guides.emberjs.com/release/models/customizing-adapters/
and here: https://guides.emberjs.com/release/models/customizing-serializers/
Your data is fairly well structured already, so conversion should hopefully go well. Comment back if you have issues <3

How to set variable Request format in Amazon Api Gateway?

I want to make a Model for request where some part of the request structure may change.
As i don't have uniform structure here. How can i define json model for Amazon Api Gateway?
Request:
Here data inside items.{index}.data is changing according to type_id. Also we are not sure about which item with perticular type_id come at which {index}. even the type of items.{index}.data may change.
{
"name":"Jon Doe",
"items": [
{
"type_id":2,
"data": {
"km": 10,
"fuel": 20
}
},
{
"type_id": 5,
"data": [
[
"id":1,
"value":2
],
.....
]
},{
"type_id": 3,
"data": "data goes here"
},
....
]
}
How should i do this?
API Gateway uses JSON schema for model definitions. You can use a union datatype to represent your data object. See this question for an example of such a datatype.
Please note that a data model such as this will pose problems for generating SDKs. If you need SDK support for strictly typed languages, you may want to reconsider this data model.

What is a correct way to handle writable M2M relationship in djangorestframework?

I have a many to many relationship between a Contact and a ContactGroup. One contact can belong to many groups, one group can contain multiple contacts.
I want to be able to display data like this, so I don't need to do multiple queries when showing names of groups where an user belongs.
GET
{
"id": 1,
"name": "Gandalf",
"groups": [
{
"id": 3,
"name": "Lord of the rings"
}
]
}
But if I update, I want to be able to update using ids or urls e.g.
POST
{
"id": 1,
"name": "Gandalf",
"groups": [
[2]
]
}
That would remove it from group 3 and put it to group 2 instead. I know I should write a Writable nested serializer, but I have two questions:
1) I want to do this properly, what is supposed to be a good practice when I want to do this. Shall I send ids or the whole objects like
POST
{
"id": 1,
"name": "Gandalf",
"groups": [
{
"id": 2,
"name": "Wizards"
}
]
}
This one seems a bit weird to me as I need to send information that is not needed (name in this case).
2) If I can go with id/url principle, how shall I do this? In a custom create/update method, I can't have id validated, because a serializer points to a GroupSerializer and doesn't accept int type, it expects GroupSerializer, so accessing validated_data.get('groups') wouldn't get me ids, it would tell me [{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]}]}
I can write 2 serializers - one for create/update and one from displaying data. Do you think it's a correct way of doing this? Am I doing a right think in a first place? What do you think of this approach?
For #1, you can leave the name as read only field in which case you'll have it for read and it'll be discarded for write operations.
For #2 as you want to remain consistent, your best take it to send:
POST
{
"id": 1,
"name": "Gandalf",
"groups": [
{"id": 2}
]
}
You really don't want to have a different style for read and write operations, really.

How to write CouchDb views?

I have list of such documents in my database of couchDB.
{
"_id": "9",
"_rev": "1-f5a9a0b76c6ae1fe5e20f1a1f9e6f8ba",
"Project": "Vaibhava",
"Type": "activity",
"Name": "Civil_Clearence",
"PercentComplete": "",
"DateAndTime": "",
"SourcePMSId": "1049",
"ProgressUpdatedToPMSFlag": "NO",
"UserId": "Kundan",
"ParentId": "5"
}
How to write a view function so that when i pass a doc._id as a key then i must get all siblings of that doc._id(docs with ParentId same as the key which I have sent)??
As said in another answer, it is not possible to do that with a single request.
However, you can do the following instead:
Define a map (with no reduce) view indexed on ParentID:
function(o) {
if (o.ParentID) {
emit(o.ParentID);
}
}
Send a first request to your object to know the ID of its parent:
GET /myDatabase/myObject
Then send a request to your view
GET /myDatabase/_design/myApp/_view/myView/?key="itsParent"&include_docs=true
Having several requests should not cause much harm here, since their number (2) is constant.
Moreover you can hide them behind a single request handled by NodeJS.
Unfortunately, you would need to chain together two map-reduce functions to achieve this result and that functionality is not available in CouchDB. See this question for further information.