Response Not getting save in model in ember - ember.js

I have to send the requests to "http:example.com/api/galleries/gallery_id/photos.The gallery_id is varying and I am getting it from params.id. Now the problem I am facing is that the response from a server is an array of objects.So what should I use?By That, I meant (findAll or findRecord).When I use FindRecord it make the correct call But is not able to serialize the data.When I use findAll it calls the wrong API.
My Serializer
import DS from 'ember-data';
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin,{
isNewSerializerAPI: true,
primaryKey:'pk',
normalize: function(typeClass, hash) {
console.log(hash)
var fields = Ember.get(typeClass, 'fields');
fields.forEach(function(field) {
var payloadField = Ember.String.underscore(field);
if (field === payloadField) { return; }
hash[field] = hash[payloadField];
delete hash[payloadField];
});
return this._super.apply(this, arguments);
}
});
This is the error I am getting is
Assertion Failed: You must include an 'id' for gallery in an object passed to 'push'

Related

What is the correct way to `push` a updated model back to store?

I am trying to push the updated model back to store. i tried with couple of ways still getting failed.
Please help me to understand to push the model back to store without updating backend api.
here is my try:
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
if(this.store.hasRecordForId('card-list', params.id)){
return this.store.peekRecord('card-list', params.id );
}
},
actions:{
formValidateBeforeNext:function(){
var model = this.controllerFor(this.routeName).get('model');
var modelId = this.controllerFor(this.routeName).get('model').get("id");
var oneTimeFee = this.controllerFor(this.routeName).get('model').get("oneTimeFee");
var monthlyInstalmentAmount = this.controllerFor(this.routeName).get('model').get("monthlyInstalmentAmount");
var updatedModel = JSON.parse(JSON.stringify(model));
updatedModel.type="card-list";
updatedModel.id="13";
console.log( "model would be:-" , updatedModel );
//sending just a updated model fails
let itemModel = this.store.push({'card-list': model });
//after stringfy trying to update still fails
let itemModel = this.store.push({'data': updatedModel });
// this.store.pushObject(JSON.parse(JSON.stringify(model)));
console.log( "store data", this.store.peekRecord('card-list', modelId ) )
this.transitionTo('cs2i.balance.balanceReview', {id:modelId});
}
}
});
What is wrong here? what is the correct way to put back the mode with updates?
UPDATE:Error added
Expected an object in the 'data' property in a call to 'push' for undefined, but was instance
Error
push method will expect the data in the expected format. for eg, if you are using the JSONAPI. the below is the expected one.
store.push({
data: {
// primary data for single record of type `Person`
id: '1',
type: 'person',
attributes: {
firstName: 'Daniel',
lastName: 'Kmak'
}
}
});
You can convert json payload into the expected form by doing so,
store.push(store.normalize('person', data));
If you are having raw JSON data, then you can try pushPayload.
this.get('store').pushPayload('card-list',data);
Refer EmberData Model Maker to know expected result format.
Read ember guides models/pushing-records-into-the-store
Read push API doc
Read pushPayload doc -

Emberjs: cannot read property 'type' of undefined

I have created a model in my ember app called ticket-stats:
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
export default Model.extend({
get_tickets_more: attr(),
get_tickets: attr(),
get_avg_tickets: attr()
});
The data is pulled from JSON api: http://domain.com/data/ticketStats?blah=blah...
So i have added a special adapter for this model called ticket-stats:
import JSONAPIAdapter from 'ember-data/adapters/json-api';
export default JSONAPIAdapter.extend({
host: 'http://domain.com',
namespace: 'data',
pathForType: function(type) {
return Ember.String.camelize(type);
}
});
I get the data for this model in route:
import Ember from 'ember';
export default Ember.Route.extend({
model () {
var ticketData;
this.store.query('ticket-stats', { teamID: 218, attUID: 'oc7569', useProd: 1})
.then(function(stats) { ticketData = stats; });
return Ember.RSVP.hash({
currentUser: this.currentUser,
ticketStats: ticketData
});
}
});
And, i get a TypeError:
ember.debug.js:32096 TypeError: Cannot read property 'type' of undefined
at _pushInternalModel (store.js:1524)
at push (store.js:1501)
at finders.js:171
at Object.Backburner.run (ember.debug.js:678)
at _adapterRun (store.js:1733)
at finders.js:168
at tryCatch (ember.debug.js:53806)
at invokeCallback (ember.debug.js:53821)
at publish (ember.debug.js:53789)
at ember.debug.js:32054onerrorDefault # ember.debug.js:32096exports.default.trigger # ember.debug.js:54476(anonymous function) # ember.debug.js:55727Queue.invoke # ember.debug.js:333Queue.flush # ember.debug.js:397DeferredActionQueues.flush # ember.debug.js:205Backburner.end # ember.debug.js:560(anonymous function) # ember.debug.js:1126
Any ideas as to why this is happening? This error goes away when i remove the pathForType function in the adapter, but then i get another error about getting the data from http://domain.com/data/ticket-stats?... which is not the correct URL. I have to convert to camelCase, ticket-stats => ticketStats.
This is what my json looks like:
{
"get_avg_tickets": { ... },
"get_tickets_more": { ... },
"get_tickets": { ... }
}
I also modified the application serializer by simply replacing JSONAPISerializer with JSONSerializer: app/serializers/application.js
import JSONSerializer from 'ember-data/serializers/json';
export default JSONSerializer.extend({
});
Any help would be appreciated! I'm very new to Ember.
you need to use this serializer here is the reference link
http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
normalizeQueryResponse(store, primaryModelClass, payload, id, requestType) {
payload = { ticketStats: payload };
return this.normalizeArrayResponse(store, primaryModelClass, payload, id, requestType);
},
});
your json should be in this format:
{
"get_avg_tickets": 45,
"get_tickets_more": propertyvalue,
"get_tickets": propertyvalue
}
otherwise you need to normalize your response in normalizeQueryreponse of serilializer
Also ready following doc for your help
http://thejsguy.com/2015/12/05/which-ember-data-serializer-should-i-use.html
i hope it will help you. dont forget to accept my answer.
you need to use serializers which are best suited for your json data.
http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html
This error is raising because your json data received from api is not fully fit into you application requirements for json formate.
Please Share json data here. because domain.com json url is not working.
there are so many issues in your code. let me to guide you one by one

Ember Data createRecord Error on switching routes

I'm getting the following error on createRecord
Uncaught Error: Assertion Failed: You may not pass `null` as id to the store's find method
Create record is called here
var newSchool = this.store.createRecord('deal', {
name: newSchoolName,
timeZone: newTimeZone,
locale: newLanguage,
gradeNames: newGradeNames,
standardSourceIds: newStandardSources,
contentSourceIds: newContentSources,
adminUserId: '511a48a7781200b2cd000001',
numOfToken: 1,
higherEd: higherEd,
dealType: 'institution',
parentDeal: this.get('model.deal')
});
The problem is with the parentDeal it's a belongTo relationship if I change it to null there's no error.
Also the error is only thrown on switching routes and if I log this.get('model.deal') before hand it shows the object.
The model is declared in the route
model: function() {
return Ember.RSVP.hash({
deal: this.store.find('deal', this.get('session.dealId')),
contentSources: this.store.find('contentSource'),
standardSources: this.store.find('standardSource')
});
},
Edit: After kitlers comments
I added the following to deactivate
deactivate: function() {
var model = this.get('model.deal');
if(model && model.get('isDirty')){
model.get('transaction').save()
}
}
Also before hand this is what the store looked like in ember inspector

Ember Data 1.13.5 RESTAdapter queryRecord

Hi according to the ember ds 1.13 release docs:
If your app is using the vanilla JSONSerializer or RESTSerializer,
you will not have to make any changes, and your app will continue to
work. The existing serializers have been updated in a backwards
compatible way to return JSON API data to the store.
Currently I am the default RESTAdapter:
export default DS.RESTAdapter.extend({
host: 'http://localhost:9990',
namespace: 'api/v1'
});
Which has a custom serailzer for the model:
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
comments: { embedded: 'always' }
}
});
When I attempt to use the new queryRecord method:
this.store.queryRecord('discussion',{ titleid: self.get('title_id')});
I get the following exception in the logs:
Error while processing route: title.index Assertion Failed: You tried to make a query but your adapter does not implement `queryRecord` Error: Assertion Failed: You tried to make a query but your adapter does not implement `queryRecord`
at new Error (native)
at Error.EmberError (http://localhost:4200/assets/vendor.js:25705:21)
at Object._emberMetalCore.default.assert (http://localhost:4200/assets/vendor.js:15895:13)
at ember$data$lib$system$store$$Service.extend.queryRecord (http://localhost:4200/assets/vendor.js:80502:15)
at loadDiscussionModel (http://localhost:4200/assets/ui.js:2728:32)
at renderTemplate (http://localhost:4200/assets/ui.js:2715:12)
at _emberRuntimeSystemObject.default.extend.setup (http://localhost:4200/assets/vendor.js:37282:14)
at Object.callHook (http://localhost:4200/assets/vendor.js:65078:38)
at handlerEnteredOrUpdated (http://localhost:4200/assets/vendor.js:63868:12)
at setupContexts (http://localhost:4200/assets/vendor.js:63836:9)
serializer/application.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
serialize: function(record) {
return this._super(record, {includeId: true});
},
isNewSerializerAPI: true
});
According to source code default adapter does not have an implementation for queryRecord method: https://github.com/emberjs/data/blob/e89732a5aefb6a81b46927da1c6f048f4aede85e/packages/ember-data/lib/system/adapter.js#L226
Nor it's defined in RESTAdapter, neither in new JSONAPIAdapter. To my mind, this is due to query requests are too specific for every project thus are hard to generalize.
Nevertheless documentation contains explanation and example of implementation: http://emberjs.com/api/data/classes/DS.Adapter.html#method_queryRecord
By the way, there are two errors:
id shold be passed as 4th argument;
type.typeKey should be replaced with typeClass.modelName.
We prefer using simpler implementation in our own project:
export default DS.RESTAdapter.extend({
...
queryRecord: function(store, type, query, id) {
return this.ajax(this.buildURL(type.modelName, id, null, 'query', query), 'GET');
}
});
You can replace id argument with null in buildUrl method if needed.
Update
I forgot to mention, that in ember-data 1.13.5 RESTAdapter's default urlForQuery implementation returns url without actual query parameters passed.
So here's out implementation based on default _buildUrl method, with id replaced by query:
urlForQuery: function(query, modelName) {
var url = [];
var host = this.get('host');
var prefix = this.urlPrefix();
var path;
if (modelName) {
path = this.pathForType(modelName);
if (path) {
url.push(path);
}
}
if (prefix) {
url.unshift(prefix);
}
url = url.join('/');
if (!host && url && url.charAt(0) !== '/') {
url = '/' + url;
}
if (query) {
var queryParams = [];
for(var paramName in query) {
if(query.hasOwnProperty(paramName)) {
queryParams.push(paramName + '=' + encodeURIComponent(query[paramName]))
}
}
if(queryParams.length > 0) {
url = url + '?' + queryParams.join('&');
}
}
return url;
}
This method is in the same adapter as queryRecord from the original answer.
Adding isNewSerializerAPI: true to the all the relevant model Serializers worked to a certain degree (it removed the Error stated below). However the original error still occurrs.
Before due to an incorrect import the following Error in the console logs was not being displayed.
Error: Assertion Failed: is using the
old serializer API and expects
it collaborates with to do the same. Make sure to set
isNewSerializerAPI: true in your custom serializers if you want to
use the new Serializer API.
Also FYI according to the documentation this flag will not be required in Ember Data 2.0:
http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html
If you have customized your serializer, you should upgrade to Ember
Data 1.13, check the upgrade guide to see if you need to make any
changes, and then set a temporary flag on your Serializer:
isNewSerializerAPI. This will opt you into the new serializer API.
Once you are on the Ember Data 2.0 train, new Serializer API is the
default one, and there is no need for a flag.

I can't find in the id of a new record from the server to update the ember model

I have this action. Data comes from a form after a createRecord, and it is saved perfectly in the database.
App.ShowController = Ember.Controller.extend({
actions: {
createShow: function() {
var self = this;
var onSuccess = function(res) {
alert('CREATED OK ' + res.get('alias'));
};
var onFail = function() {
alert('err ' + res);
};
self.get('model').save().then(onSuccess, onFail);
}
}
});
The id is generated in the database (Postgres), and I return it in a perfectly formatted json response from the app (made in Mojolicious) {"serverResponses":{"last_id":"500"}} along with a '200' status.
I can see the network response in the console, with the json data.
But how can I access the last_id value in the callback function onSuccess????
In "res" I have the original data I sent to the server, but, obviously its "id" attribute is undefined.
My idea es to "set" the returned id from the database in the "id" of the model.
I have seen a lot of questions about the returning format of the son, serialize problems, and so on, but what I really want to know is WHERE, in WHICH variable or object is the returned data?
Obviously, in case of Fail, I have the same problema. I return a perfectly formatted json with root for ember, but can't find it in the callback function onFail.
Can someone point me in the right direction?
Regards
When you create the record on the server you can return the json of the record, including ID (the same way you would return the json for a GET request). Ember data will then automatically use that response to update the model in its store. Then the argument passed to onSuccess will contain the updated model with the generated ID.
If it's not possible to change the REST api, you'll have to look into extending RESTSerializer to extract the id from the payload.
You need to configure properly your model, for example if you have an x model inside your controller create show action
//create your model locally
//acquisition is for the name of your model
//product_id is just whatever attributes you declare in your model spec
var newAcquisition = this.store.createRecord('acquisition', {
'product_id': this.get('id'),
});
//with save it calls to the server and creates the new model and retrieves a response
newAcquisition.save().then(function(response){
console.log('success - json '+response);
}, function(response){
console.log('fail - err '+response);
});
After this, you don't need to catch response to put and id, if your json response is correct, Ember will handle that response and update your newly created object with that new ID
You can save data in route to controller in setupController function
App.ShowRoute = Ember.Route.extend({
setupController: function(controller, model){
//setup form data
controller.set('formData', data);
},
actions:{
}
});