I have this router.js:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('analyses', function() {
this.route('new', { path: 'new'});
this.route('show', { path: ':analysis_id' });
this.route('edit', { path: ':analysis_id/edit'});
this.route('dataFunctions', { path: ':analysis_id/dataFunctions', resetNamespace: true }, function() {
this.route('new', { path: 'new'});
});
});
export default Router;
and these 2 models
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
dataFunctions: DS.hasMany('dataFunction', {async: true}),
});
and
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
analysis: DS.belongsTo('analysis', {async: true})
});
The contents of routes/data-functions/index.js:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
console.log(this.store.findRecord("analysis", id).get("dataFunctions"));
}
});
The contents of routes/analyses/index.js:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll("analysis");
},
setupController(controller, model) {
controller.set("analyses", model);
}
});
The contents of routes/analyses/show.js:
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('analysis', params.analysis_id);
},
setupController(controller, model) {
controller.set("analysis", model);
}
});
When I navigate to /analyses/1/dataFunctions my analysis model is loaded (it is show in ember inspector) but I can’t seem to access it in my data-functions/index.js route. How do I go about this? I need the analysis model to extend findAll in my data-function adapter to change the url for a rails-api nested resource.
I tried using this.store.modelFor("analysis").get("id") but it errors saying get is not a funcion.
I am using Ember 2.0.1 and Ember Data 2.0.0. I am lost here, any help would be greatly appreciated.
It's returning no mode found because you're returning a log statement in the dataFunctions route. Give this a try.
export default Ember.Route.extend({
model(params) {
return this.store.findRecord("analysis", params.analysis_id)
.then( (analysis) => {
return analysis.get('dataFuncitons');
})
}
});
Ok, so went through the code there was a few issues. There was a typo in analysis, and the resetNamespace is making things act weird. Also removed some of the redundant path names.
Router.map(function() {
this.route('analysis', function() {
this.route('new');
this.route('show', { path: ':analysis_id' });
this.route('edit', { path: ':analysis_id/edit'});
this.route('dataFunctions', { path: ':analysis_id/dataFunctions'}, function() {
this.route('new');
});
});
});
Rename the dataFunctions model to data-function to reflect proper conventions, e.g. using singular and dasherizing.
The analysis model
export default DS.Model.extend({
name: DS.attr('string'),
dataFunctions: DS.hasMany('data-function', {async: true}),
});
The data-function model
export default DS.Model.extend({
name: DS.attr('string'),
analysis: DS.belongsTo('analysis', {async: true})
});
Related
The master record, app/models/account:
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr('string'),
emailaddress: DS.hasMany('emailaddresses'),
birthdate: DS.attr('date'),
gender: DS.attr('boolean')
});
The detail record, app/models/emailaddress:
import DS from 'ember-data';
export default DS.Model.extend({
account: DS.belongsTo('account'),
emailaddress: DS.attr('string'),
verificationcode: DS.attr('string'),
isverified: DS.attr('string')
});
The dummy JSON string from the server:
{"id":0,"username":"ikevin","birthdate":"Jan 30, 2017 1:34:38
PM","gender":true,"emailaddresses":[{"id":0,"emailaddress":"aaa#bbb.com","verificationcode":"AAAAAA","isverified":false}]}
The adapter /app/adapters/account.js
import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
urlForQueryRecord(query) {
if (query.profile) {
delete query.profile;
return `${this._super(...arguments)}/profile`;
}
return this._super(...arguments);
}
});
The route app/route/index.js:
import Ember from 'ember';
import RSVP from 'rsvp';
export default Ember.Route.extend({
model() {
return RSVP.hash({
walletbalance: this.get('store').queryRecord('wallet', {balance: true}),
instagramfriendscount: this.get('store').queryRecord('instagram', {friendscount: true}),
accountprofile: this.get('store').queryRecord('account', {profile: true})
});
}
});
And the app/templates/components/account-profile.hbs:
<div class="box">
<div class="title">Your Profile</div>
<div>Username: {{account.accountprofile.username}}</div>
<div>Email Address: {{account.accountprofile.emailaddess}}</div>
<div>Birthdate: {{account.accountprofile.birthdate}}</div>
<div>Gender: {{account.accountprofile.gender}}</div>
</div>
I think there are 2 problems here:
In the Chrome Ember plugin, the data for model type "emailaddress" is always 0. So, that means it is not loaded.
In the app/templates/components/account-profile.hbs, {{account.accountprofile.emailaddess}}is not referring to the correct field. Note: for now it is expected to display only 1 email address.
How do I resolve these problems to load and display nested records?
Thanks!
Yes, I resolved it myself:
I changed it to Nested Arrays (as specified here: http://thejsguy.com/2016/01/29/working-with-nested-data-in-ember-data-models.html)
So the string returned from the server becomes:
{"id":0,"username":"ikevin","birthdate":"Jan 30, 2017 2:01:14
PM","gender":true,"emailaddresses":[{"emailaddress":"aaa#bbb.com","verificationcode":"AAAAAA","isverified":false}]}
And in the .hbs:
<div>Email Address: {{account.accountprofile.emailaddresses.0.emailaddress}}</div>
It displays the email address!
Thanks!
In an Ember 1.13.3 application I have this simple model :
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' } )
});
And I have this route :
import Ember from 'ember'
export default Ember.Route.extend({
model: function() {
console.log(this.store.find('skill', 1).get('name'));
return this.store.find('skill');
}
});
A request is sent at /skills/1 and this is the result :
{"skill":{"id":1,"name":"Ember","description":"JS Framework","acquired_skills":[1],"searched_skills":[1]}}
In the console, 'Ember' should be written but I have undefined.
Why I have no value for the name of the skill?
I have the same behaviour for all models and attributes.
This returns a promise:
this.store.find('skill', 1)
When you do .get('name'), it hasn't finished doing the ajax request. Instead try this:
this.store.find('skill', 1).then(function(skill){
console.log(skill.get('name'));
});
I'm trying to retrieve all the layouts for a given account.
/app/models/account.js
import DS from 'ember-data';
export default DS.Model.extend({
companyName: DS.attr('string'),
layouts: DS.hasMany('layout')
});
/app/models/layout.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
account: DS.belongsTo('account', { async: true })
});
/app/routes/layouts.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
layouts: this.store.filter('layout', { account_id: 1 }, function(layout) {
console.log(layout.get('account').content.id);
return layout.get('account').content.id === 1;
})
});
}
});
The console.log line is outputting the ID that I'm expecting (1). In Ember inspector I can see 5 layout models and under 'Belongs To' I can see: account : <DS.PromiseObject:ember960>. Clicking that brings up content : <batmics#model:account::ember600:1> and clicking that brings up the properties, including the correct ID.
But in my templates layouts is empty... and I've no idea why.
Incidentally, layouts: this.store.find('layout', { account_id: 1 }) works, but I need it to use the filter so that it's an active array.
Ember Data works with all its IDs as strings.
Changing your check to === '1' should get this going for you.
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
layouts: this.store.filter('layout', { account_id: 1 }, function(layout) {
console.log(layout.get('account').content.id);
return layout.get('account').content.id === '1';
})
});
}
});
ember-cli 0.2.7
ember 1.13-beta2
Im trying to setup a component to handle overlays in my webapp. I want to be able to open this overlay from across the application but I'm having trouble figuring out how to do so. Here is what I got.
It seems like ember doesn't recognise the service though. Any help greatly appreciated!
The service
import Ember from 'ember';
export default Ember.Service.extend(Ember.Evented, {
publish: function() {
return this.trigger.apply(this, arguments);
},
subscribe: function() {
this.on.apply(this, arguments);
},
unsubscribe: function() {
this.off.apply(this, arguments);
}
});
The navigation component
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'nav',
classNames: ['l-navigation'],
events: Ember.inject.service('event-bus'),
actions: {
openDashboard: function() {
this.get('events').publish('dashboard:open');
}
}
});
And then the 'overlay' component
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'section',
classNames: ['l-dashboard'],
events: Ember.inject.service('event-bus'),
init: function() {
this.get('events').subscribe('dashboard:open', this, 'openDashboard');
},
openDashboard: function() {
alert('opening dashboard');
}
});
EDIT - By popular demand :-)
Here is the jsbin for the issue. http://emberjs.jsbin.com/cesotamuza/1/
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.