unable to parse API response in ember - ember.js

I am trying to learn EmberJS and restify. I have get method API with following response :
{"products":[{"id":1,"name":"lappy1"},{"id":2,"name":"lappy2"}]}
This response I am getting in my browser's network log.
My product route is like :
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return {
products :this.get('store').findAll('product')
};
}
});
My product.hbs is :
<div>
<div class="row">
<div class="col-md-4"><b>id</b></div>
<div class="col-md-4"><b>Name</b></div>
</div>
{{#each model.products as |product|}}
<div class="row">
<div class="col-md-4">{{product.id}}</div>
<div class="col-md-4">{{product.name}}</div>
</div>
{{/each}}
</div>
My product model is :
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string')
});
There is no any error on log, but my page only shows header part i.e
<div class="col-md-4"><b>id</b></div>
<div class="col-md-4"><b>Name</b></div>
which thing I am missing ?

Install Chrome Ember plugin and use Chrome for debugging.
I assume you are using the RESTAdapter?
Your Route's model hook returns an object, not a promise. This is a little odd, I would recommend using a Hash:
model() {
return Ember.RSVP.hash({
products: this.store.findAll('product')
});
}
Alternately, you could just return the result of calling the store:
model() {
return this.store.findAll('product');
}
But in this case, you would change your templates to just use model instead of model.products.

Related

No access of model inside the template

I have a post route post.index inside the route,
import Ember from 'ember';
export default Ember.Route.extend({
model() {
this.get('store').findAll('post');
}
});
Inside the post hbs,
{{debugger}}
<ul>
{{#each model as |post|}}
{{post/post-item
post=post
}}
{{/each}}
</ul>
However, when I inspect the context using debugger I see null for model.
Why?
Your model should return the result.
model() {
return this.get('store').findAll('post');
}

ember - loading model data in route for power sort?

I have a very simple set up right now. I have a book model that has a name and author. I'm trying to create a simple form that will create a new book. For the author I'm using power select to load the authors from the author model. The form set up looks like this:
<form {{action "save" on="submit"}}>
{{input value=model.title placeholder="Title"}}<br>
{{#power-select class="select"
selected=model.author
options=authors
onchange=(action (mut model.author)) as |author|}}
{{author.name}}
{{/power-select}}
<input type="submit" value="Save">
</form>
However I'm having trouble setting up the route to get this working. So far no authors show up in the select, even though there are authors stored in my database. My route looks like this:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.createRecord('book');
},
actions: {
save() {
this.modelFor(this.routeName).save();
}
},
store: Ember.inject.service(),
authors: Ember.computed({
get() {
return this.get('store').findAll('author');
}
}).readOnly()
});
First of all, how should I properly load data from the author model in the route for the books/new route? Secondly, should I be doing this in the route? From what I have read, and what people have told me, loading model data should be done in the route.
Move authors property to corresponding controller.
Also you don't need to add readonly.
So in controller :
authors: Ember.computed(function(){
return this.get('store').findAll('author');
})
And for loading model in route. Yes you should load that model which is to be a resource manipulating, in route. So now you're doing it right.
1) Using Ember.RSVP.hash inside route model hook
your route file-> I assume books/new.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
newBook : this.store.createRecord('book'),
authors : this.store.findAll('author')
});
},
actions: {
save() {
this.modelFor(this.routeName).newBook.save();
}
}
});
and inside template you can access authors by using model.authors. and title by using model.newBook.title
<form {{action "save" on="submit"}}>
{{input value=model.newBook.title placeholder="Title"}}<br>
{{#power-select class="select"
selected=model.newBook.author
options=model.authors
onchange=(action (mut model.newBook.author)) as |author|}}
{{author.name}}
{{/power-select}}
<input type="submit" value="Save">
</form>
2) Like ebrahim suggested, you can have the below code in required controller,
authors: Ember.computed(function(){
return this.store.findAll('author');
})
3)As author model data is going to be shared data model for authors,books,books.new routes. so you can keep it in service and access it from all the required routes.
authors-service.js -> In service
import Ember from 'ember';
export default Ember.Service.extend({
store:Ember.inject.service(),
authors: undefined,
init(){
this._super(...arguments);
this.get('store').findAll('author', { reload: true }).then(function(results){
this.set('authors',results); //As this is going to be Ember.enumerables, you can iterate and get the data.
});
}
});
You can access authors from authors-service.js in any where by injecting it
authorsService:Ember.inject.service(). I guess in your case, you need to create controller books/new.js for books/new.hbs template,
books/new.js -> controller file
import Ember from 'ember';
export default Ember.Controller.extend({
authorsService:Ember.inject.service(),
authors: Ember.computed.alias('authorsService.authors');
});
Inside books/new.hbs template you can access authors property.

Why doesn't Ember model update?

My goal is to simply update append a number to an array model. This should create a new HTML element due to the iterator I have used in the template.
My action does get called, but the model doesn't really update.
Here is my directory structure:
- app
- routes
- compare.js
- templates
- compare.hbs
- application.hbs
- app.js
- index.html
- router.js
compare.hbs:
<div id="container">
<form method="post" name="login" {{action "submit" on="submit"}}>
<p>
Member ID
</p>
<p> {{input id="member-id" type="text"}} <input type="submit" value="Search"></p>
</form>
<div id="results">
{{#each model as |result|}}
<p>{{ result }}</p>
{{/each}}
</div>
</div>
router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('compare');
});
export default Router;
compare.js
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
results.push(123);
this.get('model').push(123);
this.refresh();
}
}
});
What is the problem?
It looks like you have a few issues. You don't need results.push as that is just adding the value to the array outside of Embers knowledge. When adding to the model use pushObject as that should notify ember of the change. There is also no need to call refresh on the model.
The documentation for pushObject shows an example very similar to what you are attempting:
http://emberjs.com/api/classes/Ember.NativeArray.html#method_pushObject
import Ember from 'ember';
let results = [12, 34, 56];
export default Ember.Route.extend({
model: function() {
return results;
},
actions: {
submit: function() {
this.model().pushObject(123);
}
}
});

Passing a relationship model through link-to helper? ember 2

Heyy!!
I'm having trouble passing a model to a route in ember cli. I'm making a simple app where posts have and author and a title. When you click the title you go to the post details and when you click the author you go to the author's profile. My problem is that I go to the respective user but when I refresh the page I get a n error in the author route. I have no idea why, I'm guessing it has to do with the model not being fetched again when I refresh since it passes the model using link-to helper
My code (client):
app/models/author.js
import DS from 'ember-data';
export default DS.Model.extend({
posts: DS.hasMany('post', {async: true}),
name: DS.attr('string'),
url: DS.attr('string')
});
app/models/post.js
import DS from 'ember-data';
var attr= DS.attr;
export default DS.Model.extend({
author: DS.belongsTo('author'),
title: attr('string'),
description: attr('string'),
date: attr('date'),
url:attr('string'),
});
app/routes/author.js
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function(controller, model) {
model.reload();
controller.set('model', model);}
});
app/templates/posts.hbs
<div class="container" style="width:70%">
{{#each model as |post|}}
<div class="well">
<div class="media">
<a class="pull-left" >
<img class="media-object" src={{post.url}} style="width:200px;height:200px">
</a>
<div class="media-body">
<h1>{{#link-to 'post' post}}{{post.title}}{{/link-to}}</h1>
<h4>Posted by: {{#link-to 'author' post.author.id}} {{post.author.name}}{{/link-to}} </h4>
<p>{{post.description}}</p>
</div>
</div>
</div>
{{/each}}
</div>
My Code (server):
var authors=[];//list of authors
var profileRouter= express.Router();
profileRouter.get('/', function(req, res) {
res.send({
'authors':authors
});
});
profileRouter.get('/:id', function(req, res) {
res.send({
'author': authors.find(function(user){
return author.id==req.params.id
// id: req.params.id,
})
});
});
app.use('/api/author', profileRouter);
You are correct that link-to is passing the model, which is not happening when the page is refreshed. You need to define the model hook on the author route (which is not called when the model is passed) -
model: function(params) {
return this.store.find('author', params.id);
}

Ember.js accessing controllers model from another controller

there is already a couple of questions asking for similar thing, but none of the answers works for me so far. I have following code, where I want to access model from UsersController in DashboardController:
JP.DashboardController = Ember.ArrayController.extend({
needs: ['users']
});
JP.UsersController = Ember.ArrayController.extend({
model: function(){
return JP.User.find();
},
sortProperties: ['id']
});
My dashboard.template looks like this:
<div class="row-fluid">
<div class="span2">
{{#if controllers.users.isLoaded}}
{{#each user in controllers.users }}
{{user.name}}
{{/each}}
{{else}}
Users not loaded
{{/if}}
</div>
<div class="span10">
{{ outlet }}
</div>
</div>
Why are users never loaded? What is wrong with my code?
Thanks
The model function in your UsersController is the cause of the problem. Always assign a real object (or object array) to the model/content property of your controller. You should do the data fetching in the Route instead of the Controller. I guess you also have a UsersRoute, if you have a UsersController? This could work:
JP.UsersRoute = Ember.Route.extend({
setupController : function(controller){
// the controller param is the instance of UsersController
controller.set("model",JP.User.find());
}
});
JP.UsersController = Ember.ArrayController.extend({
sortProperties: ['id']
});
If you have no UsersRoute and just a DashboardRoute, try this:
JP.DashboardRoute = Ember.Route.extend({
setupController : function(controller){
// the controller param is the instance of DashboardController, so we have to get the UsersController first
this.controller("users").set("model",JP.User.find());
}
});