edit record with ember data - ember.js

I wanted to make a edit record.but I can not change my value has.
/models/activite.js
import DS from 'ember-data';
export default DS.Model.extend({
nomActivite : DS.attr(),
nb : DS.attr(),
});
my function
edit(){
var controller=this.get('controller');
console.log(this.store.query('activite',{nomActivite:"work"}));
this.store.query('activite',{nomActivite:controller.get('nomAct')}).then(function (record) {
record.set('nb',controller.get('nb'));
record.save();
console.log(record.get('nb'));
});

.save() returns a promise so it may be the case that your value hasn't been sent to the backend server by the time you are hitting console.log().
Instead, use the success callback:
record.save().then(function(activite){
console.log(activite.get('nb'));
})

Related

Ember: model not being set by store in model hook route

So what I am doing is extremely basic: rendering model data to the template.
Upon setting the model hook, the {{model}} object doesn't show data in the corresponding template.
Here's my code:
contact (route):
user: Ember.inject.service('current-user'),
model: function()
{
// var that = this;
// console.log('whats being returned bitch: ', this.store.findRecord('contact', this.get('user').contactID));
//return this.store.findRecord('contact', this.get('user').contactID);
var records = this.store.findRecord('contact', this.get('user').contactID);
var promise = Ember.RSVP.defer();
// console.log('promise', promise.resolve());
// records.addObserver('isLoaded', function() {
// // console.log('records.getv', records);
promise.resolve(records);
//});
return promise;
},
setupController: function(controller)
{
// Get the parameters for the current route every time as they might change from one record to another
var params = this.paramsFor('dashboard.contact');
console.log('params', params);
// Set the data in the current instance of the object, this is required. Unless this is done the route will display the same data every time
this.module = Ember.String.capitalize(params.module);
this.id = params.id;
this.data = this.store.find(this.module,this.id);
// Set the data in the controller so that any data bound in the view can get re-rendered
controller.set('id',this.id);
controller.set('model',this.data);
controller.set('module',this.module);
}
});
First i was trying just this but it was not displaying data, then i tried deferring the promise and resolving it (like this) and finally i tried setting up the controller (setupController function) but that didn't work either since params is empty for some reason :/
contact(template):
<h1> Contact! </h1>
{{#each model as |contact|}}
<h3>{{contact.name}}</h3>
<h3>{{contact.password_c}}</h3>
{{/each}}
contact(model):
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
password_c: DS.attr('string'),
birthdate: DS.attr('string'),
assistant: DS.attr('string'),
account_name: DS.attr('string'),
email1: DS.attr('string'),
facebook: DS.attr('string'),
phone_home:DS.attr('string')
// address: Ember.computed('primary_address_street', 'primary_address_state',
// 'primary_address_city', 'primary_address_country', function() {
// return '${this.get('primary_address_street')} ${this.get('primary_address_state')} ${this.get('primary_address_city')} ${this.get('primary_address_country')}';
// })
});
Please help!
Let's assume this is your router
// app/router.js
import Ember from 'ember';
var Router = Ember.Router.extend({
});
Router.map(function() {
this.route('contacts', {path: '/contacts/:contact_id'});
});
export default Router;
and your model
// app/models/contact.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
password_c: DS.attr('string'),
});
then this is would be your contacts.js route it will have a very important role and We'll be using Ember Data's findRecord to retrieve an individual record from the data store.
// app/routes/contacts.js
import Ember from 'ember';
export default Ember.Route.extend({
model(param){
return this.store.findRecord('contact',param.contact_id);
}
});
note: this param is very important.The param is passed from the URL into the model. This posts model has an id that can be accessed via contact_id. It uses that id to look up the record so it can be returned. By default the template with the same name, contacts, will have access to this model.
Here we use Ember Data's findAll. This simply returns back all the records in the post data store.
// app/routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('contact');
}
});
now
// app/templates/application.hbs
{{#each model as |contact|}}
<h3>{{contact.name}}</h3>
<h3>{{contact.password_c}}</h3>
{{/each}}
As I don't have access to see your service and all your code I tried to simplify the way you can return all contact and get that and also how you can pass Param easily.
for more information : https://guides.emberjs.com/v2.7.0/tutorial/ember-data/
You can follow this codes and customize as you would like, I hope it will resolve your problem.
UPDATE:
If you have already your user data and it's ok, then remove {{#each}}
and let's have {{contact.name}}, that should work, you just need #each
while you have all contact like this.store.findAll('contact'); or if
you are in you must have this {{model.name}}, then model would be
contact !

find and findAll return an empty array

In an ember 1.13.3 app, I have this route :
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.find('skill');
}
});
And this model :
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
link: DS.attr('string'),
acquired_skills: DS.hasMany('users', { async: true, inverse: 'acquired_skills' } ),
searched_skills: DS.hasMany('users', { async: true, inverse: 'searched_skills' } )
});
This is the result returned by the api :
{"skills":[{"id":1,"name":"Ember","description":"JS Framework","link":null}]}
The array is empty. I can check it with this console.log(this.store.find('skill').get('length')); and I have 0.
What's wrong?
store.find() is an asynchronous operation. It returns a promise. To access the actual data you have to pass a callback to the promise. When the data is fetched from the backend, the promise resolves and executes the callback, passing the data into it:
var foo = this.store.find('skill');
console.log("typeof foo", typeof foo);
foo.then( function(result) {
console.log("result", result);
});
console.log("end of script");
The above code would produce the following output:
typeof foo, Promise
end of script
result, Object
UPD 1
You're using a JSONAPIAdapter. The payload you've shown does not comply with the JSON API spec. You should update your backend to conform to the spec.
If you can't, use the RESTAdapter and RESTSerializer as a workaround:
app/adapters/application.js
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
host: 'http://localhost:3000',
namespace: 'api/v1'
});
app/serializers/application.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
isNewSerializerAPI: false
});
More info here: http://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html

What array name does Ember Data expect for sub directory models?

I recently started learning Ember and using Ember-CLI so I'm not quite well educated about Ember Data and what array names it expects for relationships that are in sub directories in my app.
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
serverHistory: DS.hasMany("history/server", { async: true })
});
// models/history/server.js
import DS from 'ember-data';
export default DS.Model.extend({
server: DS.belongsTo("server", { async: true })
});
I've tried returning these names from my API
server_historys_ids
server_histories_ids
history_server_ids
history_servers_ids
But I don't see an XHR request for Server history in my application. The servers itself are fetched fine.
Update
I changed my relationship name and the API is returning history ids but I'm still not getting an history json request even though I'm trying to each in the template. The game relationship data is accessible in the template and a request is successfully made.
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
// attr's here.. not relevant
// Relationships
game: DS.belongsTo("game", { async: true }), // works
serverHistories: DS.hasMany("history/server", { async: true }) // doesn't make a request like game does.
});
I also have an adapter/history/server.js but it's only telling what namespace to use - "api".
Update 2
I think the problem may be in the way I'm calling the data to the model.
// routes/server/view/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var parentModel = this.modelFor("server.view");
return this.store.query("server", { server_address: parentModel.server_address });
// return this.store.find("server", 1);
}
});
How come when I use find with an id it updates the template data and when I use query with parameters it doesn't?
Update 3
So I got my find and query problem sorted out, here's the way I got it to work: https://stackoverflow.com/a/31831667/1814027
The relationship problem still persists. I see no serverHistory data in my Ember toolbar nor a request being made to the API for it.
I beleive serverHistory is anti-conventional name for hasMany and serverHistories should be instead.
export default DS.Model.extend({
serverHistories: DS.hasMany("history/server", { async: true })
});
Then in case of ActiveModelAdapter expected server payload is:
{"server": {"id": 1, "server_history_ids": [1,2,3]}}
It doesn't depend on the fact that serverHistory is namespaced model, it depends on relation name only.
For example for model:
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
bars: DS.hasMany("history/server", { async: true })
});
expected payload is:
{"server": {"id": 1, "bar_ids": [1,2,3]}}
Update
Working ember-cli example: https://github.com/artych/so_ember_data_subdir
Artych's answer helped me on the right path but Ember didn't want to recognise server_history_ids so I just renamed the hasMany relation to histories and returned histories: [] from my API. Now it works.. don't know why but it works.

How should I filter items of a user?

I am using Ember 1.13.2 and Ember Data 1.13.4. The API conforms to JSON API format (http://jsonapi.org/format).
A user has many items. Doing {{model.items}} in the template will return ALL items of the user.
What if I also need to display ONLY blue items from the user. How should I go about this?
// Route
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
// Executes: http://localhost:3099/api/v1/users/5
return this.store.findRecord('user', params.user_id);
}
})
// Template
firstName: {{model.firstName}} - works
<br>items: {{model.items}} - works
<br>blue items: {{model.items}} - what do we do about this?
// app/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
items: DS.hasMany('item', { async: true }),
firstName: DS.attr('string')
});
// app/models/item.js
import DS from 'ember-data';
export default DS.Model.extend({
user: DS.belongsTo('user', { async: true }),
name: DS.attr('string')
});
I misunderstood the original question. It seems as if you want to fetch only the items where the color is blue (and avoid fetching the rest). For this, you'll need to query the server, which requires server-side code. But, once you have the server-side code done, you can do something like this:
blueItems: Ember.computed('items.#each.color', {
get() {
const query = {
user: this.get('id'),
color: 'blue'
};
return this.get('store').find('item', query);
}
})
But again, you'll need your server to support querying for that data. (The JSON API states how you need to return the data, but you'll need to implement the query yourself.)
Old answer that filters the items after fetching for display (just for reference):
I would use a computed property:
blueItems: Ember.computed('items.#each.color', {
get() {
return this.get('items').filter((item) => {
return item.get('color') === 'blue';
});
}
})
Or the shorthand ;)
blueItems: Ember.computed.filterBy('items', 'color', 'blue')
Not every operation has an Ember shorthand which is why I gave the full example first.
Using computed properties with promises is sometimes tricky, but this computed property should update whenever your items array updates.

Ember App Deployed to Heroku Isn't Loading Data from REST API

Thanks in advance for any help.
I'm having a strange problem with a simple Ember app where, after deploying to Heroku, my models only make the REST call after the index route for the model is hit.
For example, I have two models: Resort and Forecast. Each have a belongsTo relationship, so every Resort has a Forecast and vice versa. In the resort template, there's a link to the corresponding forecast. When clicked, it properly routes to the forecast, however all the attributes in the forecast are undefined because it never made the API call to retrieve the forecasts JSON blob. I can watch the network tab in Chrome tools to verify this. When I navigate to /forecasts, the REST call is made, and the data is populated.
For whatever reason, all the API calls are made as I would expect. Once deployed to Heroku, this isn't the case.
This app is using ember-cli, and the relevant code follows:
/adapters/application.js
import DS from "ember-data";
var ApplicationAdapter = DS.ActiveModelAdapter.extend({
host: 'http://api.firstchair.io',
buildURL: function() {
var base;
base = this._super.apply(this, arguments);
return "" + base + ".json";
}
});
export default ApplicationAdapter;
/models/resort.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
state: DS.attr('string'),
latitude: DS.attr('string'),
longitude: DS.attr('string'),
region: DS.attr('string'),
token: DS.attr('string'),
weather: DS.attr('string'),
temperature: DS.attr('string'),
last_24_hours_snowfall: DS.attr('string'),
last_48_hours_snowfall: DS.attr('string'),
last_72_hours_snowfall: DS.attr('string'),
wind: DS.attr('string'),
conditions: DS.attr('string'),
baseDepth: DS.attr('string'),
humanReadableWeather: DS.attr('string'),
forecast: DS.belongsTo('forecast'),
fullDescription: function() {
return this.get('name') + ', ' + this.get('state');
}.property('name', 'state'),
currentSnowfall: function() {
return (this.get('last_24_hours_snowfall') || 0) + '"';
}.property('last_24_hours_snowfall'),
hasWind: function() {
return this.get('wind') > 0;
}.property('wind')
});
/models/forecast.js
import DS from 'ember-data';
export default DS.Model.extend({
startsAt: DS.attr('string'),
endsAt: DS.attr('string'),
weather: DS.attr('array'),
highs: DS.attr('array'),
lows: DS.attr('array'),
resort: DS.belongsTo('resort'),
days: function() {
var weather = this.get('weather');
var highs = this.get('highs');
var lows = this.get('lows');
if (!weather) { return []; }
return weather.map(function(currWeather, index) {
return {
weather: currWeather,
high: highs[index],
low: lows[index],
daysSince: index
};
});
}.property('weather', 'highs', 'lows')
});
/routes/resort.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
var resort = this.store.find('resort', params.resort_id);
console.log(resort);
console.log(resort.forecast);
return resort;
}
});
/routes/resorts.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('resort');
}
});
/routes/forecast.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log('hello');
return this.store.find('forecast', params.forecast_id);
}
});
/routes/forecasts.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('forecast');
}
});
Is there something I should be doing to ensure that the data is loaded eagerly?
You can look at the code in its entirety at: https://github.com/firstchair-io/webapp
Any insight into what might be going wrong would be greatly appreciated. Thank you.
It sounds like the relationships are not being sideloaded from the backend server. So the records contain an array of ID's in the hasMany fields, but the data itself is not sent automatically. To cause Ember Data to load the associated records, set {async: true} on the relation.