How to bind data from two tables in PhoneJs? - javascript

I have two tables:
nom_articole { id(PK), denumire, nom_um_id(FK) }
nom_um { id(PK), simbol, denumire }
I want to display:
nom_articole.id
nom_articole.denumire
nom_um.simbol
My html code:
<div data-options="dxView : { name: 'nom_articoleDetails', title: 'Nom_articole' } " >
<div data-options="dxContent : { targetPlaceholder: 'content' } " >
<div data-bind="dxScrollView: { }">
<h2 data-bind="text: nom_articole.denumire"></h2>
<div class="dx-fieldset">
<div class="dx-field">
<div class="dx-field-label">ID</div>
<div class="dx-field-value" data-bind="text: nom_articole.id"></div>
</div>
<div class="dx-field">
<div class="dx-field-label">Denumire</div>
<div class="dx-field-value" data-bind="text: nom_articole.denumire"></div>
</div>
<div class="dx-field">
<div class="dx-field-label">U.M.</div>
<div class="dx-field-value" data-bind="text: ????????????????"></div>
</div>
</div>
<div data-options="dxContentPlaceholder : { name: 'view-footer', transition: 'none' } " ></div>
</div>
</div>
My Javascrip code:
MobileApplication.nom_articoleDetails = function(params) {
return {
id: params.id,
//nom_um: new MobileApplication.nom_umViewModel(),
nom_articole: new MobileApplication.nom_articoleViewModel(),
handleDelete: function() {
DevExpress.ui.dialog.confirm("Are you sure you want to delete this item?", "Delete item").then($.proxy(function (result) {
if (result)
this.handleConfirmDelete();
}, this));
},
handleConfirmDelete: function() {
MobileApplication.db.nom_articole.remove(params.id).done(function() {
MobileApplication.app.navigate("nom_articole", { target: "back" });
});
},
viewShown: function() {
nom_articoleDetails = this;
MobileApplication.db.nom_articole.byKey(params.id).done(function(data) {
nom_articoleDetails.nom_articole.fromJS(data);
});
}
};
This code was generated by Devexpress multi-channel application wizard.

From the information you gave, and provided that nom_articole and nom_um share the same key, the code would be:
viewShown: function() {
// ... your code ...
MobileApplication.db.nom_um.byKey(params.id).done(function(data) {
nom_articoleDetails.nom_um.fromJS(data);
});
}
You uncomment the nom_um member and use text: nom_um.simbol as the binding text in the view.
Update:
To load an object by foreign key, you have two options. The first is cascading fetches:
MobileApplication.db.nom_articole.byKey(19).done(function (data) {
nom_articoleDetails.nom_articole.fromJS(data);
MobileApplication.db.nom_um.byKey(data.nom_um_id).done(function(data) {
nom_articoleDetails.nom_um.fromJS(data);
});
});
The second will work if your data service is properly configured OData. In this case you may use the expand feature:
MobileApplication.db.nom_articole.byKey(19, { expand: "nom_um" }).done(function (data) {
// data will contain a nested object
});
P.S. DevExpress provides Support service, and in case you cannot find the right answer here, you can ask them and share the solution.

Related

Only last of components get details filled

I am working on an app with cryptocurrencies, so right now I have 2 components:
MyCoins:
Vue.component('mycoins',{
data() {
return {
coins: [],
}
},
template: `
<ul class="coins">
<coin v-for="(coin, key) in coins" :coin="coin.coin_name" :key="coin.coin_name"></coin>
</ul>
`,
methods: {
getStats() {
self = this;
axios.get('api/user/coins').then(function (response) {
console.log(response.data.coins);
self.coins = response.data.coins;
})
.catch(function (error) {
console.log(error);
});
}
},
mounted() {
this.getStats();
}
})
On url 'api/user/coins' I get this data:
{"coins":
[{"id":1,"coin_name":"ethereum","user_id":1,"buy_price_usd":"341.44000","buy_price_btc":"0.14400","created_at":"2017-09-25 20:40:20","updated_at":"2017-09-25 20:40:20"},
{"id":2,"coin_name":"bitcoin","user_id":1,"buy_price_usd":"12.00000","buy_price_btc":"14.00000","created_at":"2017-09-25 21:29:18","updated_at":"2017-09-25 21:29:18"},
{"id":3,"coin_name":"ethereum-classic","user_id":1,"buy_price_usd":"33.45000","buy_price_btc":"3.00000","created_at":"2017-09-25 21:49:50","updated_at":"2017-09-25 21:49:50"},{"id":4,"coin_name":"lisk","user_id":1,"buy_price_usd":"23.33000","buy_price_btc":"0.50000","created_at":"2017-09-25 21:51:26","updated_at":"2017-09-25 21:51:26"}]}
Then I have this component: Coin:
Vue.component('coin',{
data() {
return {
thisCoin: this.coin,
coinData: {
name: "",
slug: "",
image: "https://files.coinmarketcap.com/static/img/coins/32x32/.png",
symbol: "",
price_eur: "",
price_usd: "",
}
}
},
props: ['coin'],
template: `
<li class="coin">
<div class="row">
<div class="col col-lg-2 branding">
<img :src="this.coinData.image">
<small>{{this.coinData.name}}</small>
</div>
<div class="col col-lg-8 holdings">
<p>11.34 <span>{{this.coinData.symbol}}</span></p>
<p>$ {{this.coinData.price_usd * 3}}</p>
</div>
<div class="col col-lg-2 price">
<p>{{this.coinData.price_usd}}</p>
</div>
<div class="edit col-lg-2">
<ul>
<li>
<p>Edit</p>
</li>
<li>
<p>Delete</p>
</li>
</ul>
</div>
</div>
</li>
`,
methods: {
getCoin: function(name) {
self = this;
axios.get('api/coin/' + name).then(function (response) {
console.log(response);
self.coinData.name = response.data.coin.name;
self.coinData.price_usd = response.data.coin.price_usd;
self.coinData.price_eur = response.data.coin.pride_eur;
})
.catch(function (error) {
console.log(error);
});
}
},
mounted() {
this.getCoin(this.coin);
}
})
On url 'api/coin/{name}' I get this data:
{"coin":{"slug":"lisk","name":"Lisk","symbol":"LSK","rank":14,"price_usd":"6.15510","price_btc":"0.00156","24h_volume_usd":null,"market_cap_usd":"99999.99999","available_supply":"99999.99999","total_supply":"99999.99999","percent_change_1h":"0.10000","percent_change_24h":"6.78000","percent_change_7d":"-5.64000","last_updated":1506385152,"price_eur":"5.19166","24h_volume_eur":null,"market_cap_eur":"99999.99999","created_at":"2017-09-25 00:06:27","updated_at":"2017-09-26 00:23:02"}}
But as of right now, only the last component gets the details filled (name, price_usd, price_eur, etc.), but not the first 3 ones.
Here is the video of loading the page: https://gfycat.com/gifs/detail/BreakableSlimHammerkop - You can see it goes trough all the coins it should pass to the first three components. What am I doing wrong?
The problem is because the self variables you've declared in your getStats() and getCoin() methods are bound to the window object, and not properly scoped to each method. A simple fix would be to replace each self = this; statement with var self = this;.
Let me explain.
When you declare a new variable without using the var, let or const keywords, the variable is added to the global scope object, which in this case is the window object. You can find more info about this JavaScript behaviour here https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/ or check the var docs on MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var)
You shouldn't directly reassign data value because Vue cannot detect property additions and rerender view. You should do it via Vue.set or this.$set like this:
self.$set(self.coinData, 'name', response.data.coin.name)
...

Binding events to views - Firing uneven number of times

I have UserModel: UserView and UserCollection: UserCollectionView. With this, I am trying to bind a click event to the UserView (I am doing this in UserView). So, this is the code I have:
var root = 'http://localhost:5000/api/v1';
var app = {};
// Backbone Model
app.UserModel = Backbone.Model.extend({
defaults: {
// urlRoot: root + '/users',
name: 'Default Name',
email: '30',
username: 'default_username'
},
initialize: function() {
this.set({
id: this.get('username')
});
console.log('User model \'' + this.id + '\' has been initialized.');
},
// parse: function(data) {
// console.log('Model parse funciton called');
// return data;
// }
});
// Backbone Model View
app.UserView = Backbone.View.extend({
// el: '#users-list',
// tagName: 'div',
el: '.user-box-wrapper',
events: {
'click .user-data': 'userClicked'
},
userClicked: function(ev) {
console.log("User selected");
// console.log(ev.currentTarget);
},
template: _.template($('#connections-user-template').html()),
initialize: function() {
this.render();
},
render: function() {
$('#users-list').append(this.template(this.model.toJSON()));
// this.$el.append( this.template( this.model.toJSON()));
console.log('User view is rendered');
}
});
// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
model: app.UserModel,
url: root + '/users',
initialize: function() {
// this.fetch();
},
parse: function(data) {
// console.log(data.data);
return data.data;
}
});
// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
el: '#users-list',
template: _.template($('#connections-template').html()),
initialize: function() {
this.connections = new app.UserCollection();
var self = this;
this.connections.fetch().done(function() {
self.render();
});
},
render: function() {
console.log('User collection view is rendered');
this.$el.html(this.template());
// this.$el.append( this.template( this.model.toJSON()));
this.connections.each(function(user) {
console.log('User : ' + user.get('id'));
var userView = new app.UserView({
model: user
});
// userView.model.fetch();
// userView.render();
});
}
});
var connectionsView = new app.UserCollectionView();
The JSON data actually returns 14 objects (or UserModels in this case). The problem is, if I click the first user view, it is triggered 13 times, and the second view click is triggered 12 times and so on, the last view click event not being triggered at all when clicked.
The individual UserViews are rendered once each, however (that's what I think at least). Can someone please explain what the problem here is and what exactly is happening here?
P.S. - I am aware of the workaround of binding the events in the CollectionView.
Edit 1
This is the DOM structure:
<!doctype html>
<html>
<head>
<title>Hey there</title>
<link rel="stylesheet" href="../static/css/normalize.css">
<link rel="stylesheet" href="../static/css/index.css">
<script src="/static/js/jquery-2.2.0.js"></script>
<script src="/static/js/underscore-1.8.3.js"></script>
<script src="/static/js/backbone-1.2.3.js"></script>
</head>
<body>
<header id="top">
<div id="logo-wrapper">
<img src="../static/img/logo.png" alt="Logo" id="logo">
</div>
<div id="top-links">
<div id="top-profile-box" class="toplink">
<div id="top-profile-data-box">
<div id="top-profile-data-name">Kevin Isaac</div>
<div id="top-profile-data-passion">Writer</div>
</div>
<img id="top-profile-image" src="../static/img/user1.jpg" alt="">
</div>
<div id="notification-icon" class="toplink"></div>
<div id="top-message-icon" class="toplink"></div>
<div id="logout-icon" class="toplink"></div>
</div>
</header>
<div id="middle">
<nav id="side-nav">
<div id="side-nav-top">
<div class="side-nav-link" id="side-nav-home-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Home</div>
</div>
<div class="side-nav-link" id="side-nav-profile-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Profile</div>
</div>
<div class="side-nav-link" id="side-nav-messages-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Message</div>
</div>
<div class="side-nav-link" id="side-nav-account-link">
<div class="side-nav-link-img"></div>
<div class="side-nav-link-title">Account</div>
</div>
</div>
</nav>
<div id="main-content">
<!-- Start of page specific HTML -->
<div id="content-title">
<div class="content-subtitle" id="connections">Connections</div>
<div class="content-subtitle" id="followers">Followers</div>
<div class="content-subtitle" id="followings">Followings</div>
</div>
<div id="content-body">
<div id="users-box">
<div id="users-list">No connection</div>
<!-- Backbone Template Starts -->
<script type="text/template" id="connections-template"></script>
<script type="text/template" id="connections-user-template">
<div class="user-box-wrapper">
<div class="user-box">
<div class="user-pic-wrapper">
<img src="/static/img/user1.jpg" alt="">
</div>
<div class="user-data" id="boox">
<div class="user-name"><%= name %></div>
<div class="user-passion"><%= username %></div>
<div class="user-city"><%= email %></div>
</div>
</div>
</div>
</script>
<!-- Backbone Template Ends -->
<div id="users-side-box">
<div id="users-box-search">
<input id="user-search" type="text" name="">
</div>
<div id="user-metadata">
<div id="metadata-user-top-box">
<div id="metadata-user-image-wrapper">
<img src="/static/img/user1.jpg" alt="">
</div>
<div id="metadata-user-name-box">
<div id="metadata-name">Name's Bond</div>
<div id="metadata-passion">Assassin</div>
</div>
</div>
<div id="metadata-user-bottom-box">
<div class="metadata-user-attribute">
<span class="metadata-property">Studied at: </span>
<span class="metadata-value">Karunya University </span>
</div>
<div class="metadata-user-attribute">
<span class="metadata-property">Native City: </span>
<span class="metadata-value">London</span>
</div>
<div class="metadata-user-attribute">
<span class="metadata-property">Website: </span>
<span class="metadata-value">www.007.com</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End of page specific HTML -->
</div>
<aside id="main-aside">
Aside one two therr
</aside>
</div>
<script src="../static/js/index.min.js"></script>
</body>
</html>
There are many issues with your code.
Main problem is that, all your userView's are pointing to the same selector, and the element matching this selector .user-box-wrapper is inside the view template - So whenever you create a new userView, it'll add a new event listener to .user-box-wrapper present in all existing userViews, but not to itself. So your first userView will have n-1 events handlers registered to it while last one has none (n being total number of userViews). View element is not supposed to be part of template, template is supposed to be added to the view element.
When your view will have multiple copies of itself, don't define el option, let backbone create a new element for each instance of the view. You can customize the properties of this element.
Another issue is that you are not appending the userView template to your userView element, but something else outside it ($('#users-list'). So clicking the template won't trigger the event handler (in your case this is why you're last userView doesn't fire it's event. It was bound to all other existing views because common selector was provided by el)
You should try to avoid global selectors like $('#users-list') from within a view. In this case you can append the userView to #users-list from within userCollectionView who's el points to #users-list.
Your code should be:
var root = 'http://localhost:5000/api/v1';
var app = {};
// Backbone Model
app.UserModel = Backbone.Model.extend({
defaults: {
// urlRoot: root + '/users',
name: 'Default Name',
email: '30',
username: 'default_username'
},
initialize: function() {
this.set({
id: this.get('username')
});
console.log('User model \'' + this.id + '\' has been initialized.');
}
});
// Backbone Model View
app.UserView = Backbone.View.extend({
className: 'user-box-wrapper',
/*--^-- creates a new div with this class for each user*/
template: _.template($('#connections-user-template').html()),
events: {
'click .user-data': 'userClicked'
},
initialize: function() {
this.render();
},
render: function() {
this.$el.append( this.template( this.model.toJSON()));
console.log('User view is rendered');
},
userClicked: function(ev) {
console.log("User selected");
// console.log(ev.currentTarget);
}
});
// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
model: app.UserModel,
url: root + '/users',
initialize: function() {
// this.fetch();
},
parse: function(data) {
// console.log(data.data);
return data.data;
}
});
// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
el: '#users-list',
template: _.template($('#connections-template').html()),
initialize: function() {
this.connections = new app.UserCollection();
var self = this;
this.connections.fetch().done(function() {
self.render();
});
},
render: function() {
this.$el.html(this.template());
console.log('User collection view is rendered');
this.connections.each(function(user) {
console.log('User : ' + user.get('id'));
var userView = new app.UserView({
model: user
});
this.$el.append(userView.el); /*append child view here*/
},this);
}
});
var connectionsView = new app.UserCollectionView();
The main problem is that you are rendering all UserView views in the same container:
$('#users-list').append(this.template(this.model.toJSON()));
This is why the click event selector('click .user-data') is selecting the other UserView buttons and firing it's clicks too.
You didn't ask but... here it goes some suggestions:
Do not call render from the initialize function;
Avoid defining the el;
Avoid adding the view content outside the view using $. Use
this.$el instead;
NEVER forget to return this; at you render functions.
Here is a jsfiddle with what I think you want:
https://jsfiddle.net/Neviton/n52j873u/

Angular - can I use a single function on multiple objects within a nested ng-repeat that triggers the ng-show of just that object?

SUMMARYI have a list of brands and a list of products. I am using an ng-repeat to show the list of brands, and an ng-repeat with a filter to show the list of products within their respective brands. I want each brand and each product to have a button that shows more about that brand/product. All of these buttons should use the same function on the controller.
PROBLEMThe button that shows more about the brand also shows more about each of that brand's products, UNLESS (this is the weird part to me) I click the button of a product within that brand first, in which case it will work correctly.
CODEPlease see the Plunker here, and note that when you click on 'show type' on a brand, it also shows all the types of the products within that brand: http://plnkr.co/edit/gFnq3O3f0YYmBAB6dcwe?p=preview
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="MyController as vm">
<div ng-repeat="brand in brands">
<h1>
{{brand.name}}
</h1>
<button ng-click="showType(brand)">
Show Brand Type
</button>
<div ng-show="show">
{{brand.type}}
</div>
<div ng-repeat="product in products
| filter:filterProducts(brand.name)">
<h2>
{{product.name}}
</h2>
<button ng-click="showType(product)">
Show Product Type
</button>
<div ng-show="show">
{{product.type}}
</div>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
JAVASCRIPT
var app = angular.module('myApp', []);
app.controller('MyController', function($scope) {
$scope.brands = [{
name: 'Kewl',
type: 'Cereal'
}, {
name: 'Joku',
type: 'Toy'
}, {
name: 'Loko',
type: 'Couch'
}]
$scope.products = [{
name: 'Kewlio',
type: 'Sugar Cereal',
brand: 'Kewl'
}, {
name: 'Kewliano',
type: 'Healthy Cereal',
brand: 'Kewl'
}, {
name: 'Jokurino',
type: 'Rattle',
brand: 'Joku'
}, {
name: 'Lokonoko',
type: 'Recliner',
brand: 'Loko'
}, {
name: 'Lokoboko',
type: 'Love Seat',
brand: 'Loko'
}]
$scope.showType = function(item) {
this.show = !this.show;
}
$scope.filterProducts = function(brand) {
return function(value) {
if(brand) {
return value.brand === brand;
} else {
return true;
}
}
}
});
IMPORTANT NOTE: I realize I could add an attribute to the object (brand.show) and pass the object into the function, then change that attribute to true/false, but I don't want to do this because in my actual application, the button will show a form that edits the brand/product and submits the info to Firebase, and I don't want the object to have a 'show' attribute on it. I would rather not have to delete the 'show' attribute every time I want to edit the info in Firebase.
ng-repeat directive create own scope, when you do
this.show = !this.show
you create/change show property in current scope, if click brand button - for brand scope, that global for product, and when click in product button - for scope concrete product.
To avoid this, you should create this property before clicking button, for example with ng-init, like
ng-init="show=false;"
on element with `ng-repeat" directive
Sample
var app = angular.module('myApp', []);
app.controller('MyController', function($scope) {
$scope.brands = [{
name: 'Kewl',
type: 'Cereal'
}, {
name: 'Joku',
type: 'Toy'
}, {
name: 'Loko',
type: 'Couch'
}]
$scope.products = [{
name: 'Kewlio',
type: 'Sugar Cereal',
brand: 'Kewl'
}, {
name: 'Kewliano',
type: 'Healthy Cereal',
brand: 'Kewl'
}, {
name: 'Jokurino',
type: 'Rattle',
brand: 'Joku'
}, {
name: 'Lokonoko',
type: 'Recliner',
brand: 'Loko'
}, {
name: 'Lokoboko',
type: 'Love Seat',
brand: 'Loko'
}]
$scope.showType = function(item) {
this.show = !this.show;
}
$scope.filterProducts = function(brand) {
return function(value) {
if (brand) {
return value.brand === brand;
} else {
return true;
}
}
}
});
/* Styles go here */
h1 {
font-family: impact;
}
h2 {
font-family: arial;
color: blue;
margin-bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController as vm">
<div ng-repeat="brand in brands" ng-init="show=false">
<h1>
{{brand.name}}
</h1>
<button ng-click="showType(brand)">
Show Brand Type
</button>
<div ng-show="show">
{{brand.type}}
</div>
<div ng-repeat="product in products
| filter:filterProducts(brand.name)" ng-init="show=false">
<h2>
{{product.name}}
</h2>
<button ng-click="showType(product)">
Show Product Type
</button>
<div ng-show="show">
{{product.type}}
</div>
</div>
</div>
</div>
</div>
The easiest fix for this, if you don't mind putting temporary properties in your data is the following changes:
<div ng-show="product.show">
{{product.type}}
</div>
and
<div ng-show="brand.show">
{{brand.type}}
</div>
and then in your controller
$scope.showType = function(item) {
item.show = !item.show;
}
Alternatively, if you don't want to touch the object properties, you can create an $scope.shownTypes array and have your click either push the object into or remove the object from the shown array. THen you can check for the object's existence in the array and show or not show the type appropriately. Let me know if you need a sample of that.
Your show boolean attribute same for whole tree (is in same scope). Using angular directive with child scope scope:true in ng-repeat helps to isolate each show property. I have forked your plunker code:
http://plnkr.co/edit/cMSvyfeCQOnTKG8F4l55?p=preview

AngularJS view not getting updated with model changes

Controller (snippet, as its very large):
function loadImages() {
if (Authentication.loggedIn()) {
Images.get(function(s) {
$scope.images = s.images;
},
function(f) {} );
}
}
$scope.loginOnSubmit = function() {
Authentication.login($scope.model.login).then(
function(okResponse) {
WizardHandler.wizard().next();
loadImages()
},
function(failureResponse) {
// TODO: Alert use with the failure
}
);
};
loadImages();
View:
<wz-step title="{{ strings.images.bullet }}">
<div class="row">
<div class="col-md-10">
<h1 ng-bind="strings.images.title"></h1>
<p ng-bind="strings.images.description"></p>
<div ui-grid="{ data: images }" class="imagesGrid"></div>
</div>
</div>
</wz-step>
using angular-wizard wizard plugin (wz-step directive..).
I've looked over the web, thought its related to the $digest, etc.
I've tried using $timeout(...) to overcomes this, no go.
what happens is, the data doesnt show up in the view, but when I refresh the page, then its there, or when I even re-size the page, it appears.

Child outlet goes empty when I refresh the url with id from {{link-to}} in Emberjs

I have a weird issue, the child outlet goes empty whenever I will refresh the page with the id. I have a list generated by {{link-to}} helper.
<script type="text/x-handlebars" id="twod">
<div class="row">
<div class="span4">
<img src="/img/2DPipeline.jpg" />
</div>
<div class="span3">
<h4>People with Roles</h4>
<div class="row">
<div class="span2">
<ul>
{{#each item in model}}
<li>{{#link-to 'twoduser' item}}{{item.firstname}} {{/link-to}}</li>
{{/each}}
</ul>
</div>
<div class="row">
<div class="span">
{{outlet}}
</div>
</div>
</div>
</div>
</script>
Here's the twoduser template,
<script type="text/x-handlebars" data-template-name="twoduser">
<div class="row">
<div class="span3">
Full Name: {{firstname}}{{lastname}}
EMail: {{email}}
</div>
</div>
</script>
App.js,
App.Router.map(function() {
this.resource('twod', function() {
this.resource('twoduser', {
path : ':user_id'
});
});
this.resource('threed');
});
App.TwoduserRoute = Ember.Route.extend({
model : function(params) {
return App.Twod.findBy(params.user_id);
}
});
App.Twod.reopenClass({
findAll : function() {
return new Ember.RSVP.Promise(function(resolve, reject) {
$.getJSON("http://pioneerdev.us/users/index", function(data) {
var result = data.users.map(function(row) {
return App.Twod.create(row);
});
resolve(result);
}).fail(reject);
});
},
findBy : function(user_id) {
var user = App.Twod.create();
$.getJSON("http://ankur.local/users/byId/" + user_id, function(data) {
user.setProperties(data.user);
});
user.set("user_id", user_id);
return user;
}
});
App.TwodRoute = Ember.Route.extend({
model : function() {
return App.Twod.findAll();
}
});
Selecting each one individually works fine and fills the child outlet, but when I refresh it, it goes blank.
Any ideas what might be causing the issue?
I can see two possible problems.
The first is that your URLs are different between findAll and findBy. Was that intentional?
The second is that findAll returns an Ember promise (Ember.RSVP.Promise), but findBy does not.
[UPDATE] : Based on the JSBin in the comments : http://jsbin.com/iPUxuJU/1/
The problem here is that the API endpoint is returning an array in the user response. It currently looks like this:
{user : [{ ... }] }
Ideally it would look like this :
{user : {....} }
You could change the API endpoint, or you could update your code to pull the first element from that array. Instead of :
user.setProperties(data.user);
You could do :
user.setProperties(data.user[0]);
Here's an altered JSBin : http://jsbin.com/oquBoMA/1#/twod/2

Categories

Resources