How to properly use Fixtures with ember-cli project structure - ember.js

I'm using ember-cli and trying to make some sense of the structure of the app and how it is all wired together. There are some differences in the main Ember guide docs and what I'm seeing in the ember-cli generated project. I understand the API's are moving fast so I just need to be pointed in the right direction.
In router.js I have the following:
Router.map(function() {
this.route('domains', {path: "/domains" });
});
Then I have models/domain.js
import DS from 'ember-data';
var Domain = DS.Model.extend({
name: DS.attr('string')
});
Domain.reopenClass({
FIXTURES: [
{ id: 1, name: 'User'},
{ id: 2, name: 'Address'}
]
});
export default Domain;
And I have routes/domains.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.all('domain');
}
});
And finally ( I think ), I have templates/domains.hbs
<h1>Domains</h1>
{{#each}}
<p>{{name}}</p>
{{/each}}
Only the header is being rendered when I visit the http://localhost:4200/domains url. I'm using the ember chrome extension and I don't see any data coming back in the request. I'm not sure if it is a naming convention issue or what I'm doing wrong so any help is appreciated.

all just returns records that have already been found in the store. find will issue a request (in this case hitting the fixtures) and populate the store, and also return all of the records in the store.
this.store.find('domain');

The problem ended up being 2-fold. Kingpin2K was right in that I needed to use find instead of all. I also had to change the adapter to the following in adapters/application.js:
export default DS.FixtureAdapter.extend();

Related

Assertion Failed: You need to pass a model name to the store's modelFor method

Pretty new to Ember so maybe someone can help me out. I keep running across this error and have no idea how to solve it.
Ember : 2.5.1
Ember Data : 2.5.3
Below is my router.js.
//app/router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('organization', {path: '/organization/:id'}, function(){
this.route('about', { path: '/about' });
this.route('admin', { path: '/admin' }, function(){
this.route('team', { path: '/team/:team_id' });
});
});
});
The organization/:id/about and organization/:id/admin routes work fine. But when I try to load the organization/:id/admin/team/:team_id route, the error is thrown. Below is the routes/organization/admin/team.js file:
//app/routes/organization/admin/team.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
let organization = this.modelFor('organization');
return organization.get('team');
}
});
Not really sure what other information I should post, so please ask for any additional information you may think is necessary to help debug. My guess is it's something pretty simple and I'm completely oblivious to it.
EDIT
I've added a couple more files to help diagnose the problem:
//app/routes/organization.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('organization', params.organization_id)
}
});
//app/routes/organization/admin.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
changeValue(){
this.currentModel.save();
}
}
});
Where currentModel is the model for the organization route. I've removed the organization.admin.team model hook for now and am just testing a
{{#link-to 'organization.admin.team' model.team.id}} Team {{/link-to}}
in a component rendered in the organization.admin template where I pass model=model. But now I get the same error (Assertion Failed: You need to pass a model name to the store's modelFor method) in the Javascript console when rendering the organization.admin template.
If you pass Object to {{#link-to}} helper. It skips the model hook. So you could basically send {{#link-to 'team' organization.team}}Without having to write "model" hook.
"It makes sense and it might save a request to the server but it is, admittedly, not intuitive. An ingenious way around that is to pass in, not the object itself, but its id" - https://www.toptal.com/emberjs/the-8-most-common-ember-js-developer-mistakes".
So you should do
hbs
{{#link-to 'team' organization.team.id}} Link to team management {{/link-to}}
route
model(params) {
return this.store.findRecord('team', params.team_id)
}
you can use modelFor('parent') method to get organization model.
like that
//app/routes/organization/admin/team.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
let organization = this.modelFor('parent');
return this.store.findRecord('team', params.team_id)
}
});
i think you wants to do something like that.
basically ember does not support nested routes.

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.

Cannot read property 'match' of undefined at Ember.DefaultResolver.extend.podBasedComponentsInSubdir

I'm getting a really opaque error message (opaque in the sense I have no point of reference for my own source) from console, I'm not entirely sure where to look, I feel it's likely an error in library code but before posting this on github I'll just double check it's not my own fault.
The Problem
The Problem is simple, I'm calling this.store.find('player'), in hopes to get a list of all players, and then display them in some kind of list, but I'm not even getting past the loading part. The data is pulled from the server and looks properly formatted, but something seems to be failing after the route.model method call. And the error message seems to be somewhere in the ember.js library code with nothing pointing back to my own code.
Server Response
The content type is of course application/json, and note the id property is actually _id.
[
{
"_id":"55405a5102b4ed623c225e87",
"alias":"mikeTest",
"__v":0,
"scans":[],
"createdAt":"2015-04-29T04:13:05.223Z"
}
]
Error message
Note there is part of the stack trace pointing to my source, only Ember source. Which has made this a pain to debug.
Error while processing route: leader Cannot read property 'match' of undefined TypeError: Cannot read property 'match' of undefined
at Ember.DefaultResolver.extend.podBasedComponentsInSubdir (http://localhost:4200/assets/vendor.js:60138:76)
at http://localhost:4200/assets/vendor.js:60190:34
at Array.exports.default.mixin.Mixin.create.find (http://localhost:4200/assets/vendor.js:39572:30)
at Ember.DefaultResolver.extend.findModuleName (http://localhost:4200/assets/vendor.js:60188:44)
at resolveOther (http://localhost:4200/assets/vendor.js:60051:37)
at superWrapper (http://localhost:4200/assets/vendor.js:28141:20)
at exports.default.EmberObject.default.extend.resolve (http://localhost:4200/assets/vendor.js:15454:35)
at Object.resolve [as resolver] (http://localhost:4200/assets/vendor.js:15217:23)
at resolve (http://localhost:4200/assets/vendor.js:12792:29)
at Object.Registry.resolve (http://localhost:4200/assets/vendor.js:12336:21)
Source
This ember app is very young, so there is very little source at the moment, but this is all the relevant source at the moment.
Routes
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
export default Router.map(function() {
this.resource('leader');
this.resource('profile');
this.route('loading');
});
Leader route
Leader has a template and a controller, but they are basically empty right now.
import Ember from 'ember';
export default Ember.Route.extend({
model: function () {
return Ember.RSVP.hash({
players: this.get('store').find('player')
});
},
});
Player Model
import DS from 'ember-data';
export default DS.Model.extend({
alias: DS.attr('string'),
createdAt: DS.attr('date'),
scans: DS.hasMany('scan'),
});
Application Adapter
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
namespace: ''
});
Application Serialiser
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
primaryKey: function (type) {
return '_id';
},
serializeId: function(id) {
return id.toString();
}
});
Versions
I'm not sure if any of the versions here are particularly important
ember-cli is 0.2.3
ember-data is 1.0.0-beta.16.1
ember is 1.11.1
Things I've tried
removing properties from the model, in the event the relationships seemed to be the problem (nothing changed)
tried setting up a serialiser and adapter for the application (included above), nothing changed.
the serialiser in the event that the id field in the response is actually _id.
tried updating ember data, nothing changed.
Okay I figured out what was being done wrong... I forgot to check if the data being returned by the server abides to the convention/protocol required to use ember data. The JSON returned by the server looks like this.
[
{
"_id":"55405a5102b4ed623c225e87",
"alias":"mikeTest",
"__v":0,
"scans":[],
"createdAt":"2015-04-29T04:13:05.223Z"
}
]
It should actually look like this
{
"players": [
{
"_id":"55405a5102b4ed623c225e87",
"alias":"mikeTest",
"__v":0,
"scans":[],
"createdAt":"2015-04-29T04:13:05.223Z"
}
]
}
So yes this was me being dumb and missing something.
Why is this Required
Ember data expects JSON returned from the server to meet the JSON API Standard, which is a standard that specifies the formatting of the JSON returned from a server. In this case, the data didn't meet the JSON API standard, as I forgot to put the array of players under a key called players. There are some more examples of this in the Ember v1.10.0 guide to models.
The reason Ember Data expects this is so Ember Data can make the certain assumptions about the data returned from the server.

EmberCLI app errors when using fixtures

I usually use Rails for my Ember apps. However this time we opted to decouple the API from the Ember app, and as such I'm trying EmberCLI. So far it's lovely to setup and use. However when using attempting to use fixtures it doesn't load the data.
As listed in this post I am using reopenClass when declaring the fixtures.
If I do not override the model, it does not error but the Ember inspector also shows no data was loaded. If I override my file with:
// routes/campaigns/index.js
export default Ember.Route.extend({
model: function() {
return this.store.find('campaign');
}
});
And visit the /campaigns path then I get the error I get the error Error while loading route: undefined.
From what I can find this seems to happen when Ember cannot find the data.
My router and model with obvious items like export default excluded:
// app/router.js
Router.map(function() {
this.resource('campaigns', function() {
});
});
// models/campaign.js
var Campaign = DS.Model.extend({
name: DS.attr('string')
});
Campaign.reopenClass({
FIXTURES: [
{ "id": 1, "name": "Campaign #1" },
{ "id": 2, "name": "Campaign #2" }
]
});
I have tested the same setup in a Rails app I just made, and it works perfectly. I'd love any insight people could give, as EmberCLI seems lightweight and worth the effort.
Edit: Adding my app.js file to answer question about whether I included DS.FixtureAdapter:
// Import statements
Ember.MODEL_FACTORY_INJECTIONS = true;
var App = Ember.Application.extend({
modulePrefix: 'nala', // TODO: loaded via config
Resolver: Resolver
});
loadInitializers(App, 'nala');
App.ApplicationAdapter = DS.FixtureAdapter({});
export default App;
You need to set up your application adapter located at the filepath adapters/application.js as follows:
export default DS.FixtureAdapter.extend({});
See the first paragraph under ember-cli Naming Conventions. N.B. you won't need to import DS or Ember if you're using ember-cli and have them listed in your .jshintrc file.

Integrate cloudinary_js with ember

I am working on my first ember application using Ember-cli
Here i want to add feature of image-upload using cloudinary_js
Referring this link
Image Model:
import DS from 'ember-data';
var attr = DS.attr;
export default DS.Model.extend({
imageUrl: attr('string'),
thumbImageUrl: attr('string'),
standardImageUrl: attr('string'),
favourite: attr('string'),
order: attr('number')
});
I have already added the required js files using bower and listed them in Brocfile.js
app.import('vendor/jquery-ui/jquery-ui.js');
app.import('vendor/jquery.iframe-transport/jquery.iframe-transport.js');
app.import('vendor/blueimp-file-upload/js/jquery.fileupload.js');
app.import('vendor/cloudinary_js/js/jquery.cloudinary.js');
Added file field as component:
import Ember from "ember";
export default Ember.View.extend({
tagName: "input",
type: "file",
accept: "image/*",
class: "cloudinary-fileupload",
dataCloudinaryField: "image_id",
attributeBindings: [ "name", "type", "value", "class"],
change: function() {
}
});
Here am stuck with, where to specify the config of cloudinary (cloud name and api key)?
Can anyone please help me with the detailed steps of cloudinary integration with ember using ember-cli.
Thanks.
You'll want to have an initializer that sets the cloud_name and api_key properties. I would put this code in app/initializers/cloudinary.js.
export default {
name: 'cloudinary',
initialize: function() {
$.cloudinary.config({
cloud_name: 'MYCLOUD',
api_key: 'MYKEY'
});
}
};
I wrote a detailed blog post on how to integrate cloudinary_js and Ember a few days ago. There's an example app that uses ember-cli and shows how to configure Cloudinary and everything you'd need to get it up and running. There are some tricky parts to getting the whole thing working, so I'd recommend checking that out if you get tripped up after the config setup right.