Whenever a user is not authenticated they are transitioned to the login route/view. I am needing a way for a user to be able to get to a few routes when they aren't authenticated like 'password-reset', 'new-password', etc. Is there a way to whitelist the requested route and if it's not one of those routes transition to the login route? Thanks in advance for the help.
App.ApplicationRoute = Ember.Route.extend
model: ->
store = #controllerFor('application').get('store')
if !$.cookie('apiKey')
#transitionTo 'login'
return store.createRecord('session')
store.find('session', 'current').then (session)->
session
, (error)=>
if error.status == 403
#transitionTo 'login'
return store.createRecord('session')
else
throw error
App.Router.map(function() {
this.resource('auth', function(){
this.resource('colors', {path:'/colors'}, function(){
this.resource('color', {path: '/:id'});
});
});
this.resource('unauth', function(){
this.resource('dogs', {path:'/dogs'}, function(){
this.resource('cats', {path: '/:id'});
});
});
});
App.AuthRoute = Em.Route.extend({
model: function(){
store = #controllerFor('application').get('store')
if !$.cookie('apiKey')
#transitionTo 'login'
return store.createRecord('session')
store.find('session', 'current').then (session)->
session
, (error)=>
if error.status == 403
#transitionTo 'login'
return store.createRecord('session')
else
throw error
}
});
Related
Somehow the parameter user_id is not being passed to my UserIndexRoute. What could be going wrong?
The error I'm getting as a result is
Assertion Failed: You may not pass undefined as id to the store's
find method
The request is /users/1
A user with id 1 does exist in its model fixtures
There are no other errors in my app, the users route is working and showing the fixturedata for user
router.js
var Router = Ember.Router.extend({
location: DaappEmber2ENV.locationType
});
Router.map(function() {
this.resource('users', function(){
this.resource('user', { path:'/:user_id' }, function(){
this.route('edit');
});
this.route('create');
});
});
export default Router;
routes/user/index.js
export default Ember.Route.extend({
model: function(params){
Ember.Logger.debug('Params for user/index route:', params);
return this.store.find('user', params.user_id);
}
});
You've defined a dynamic slug, user_id on the users route, but then you are trying to access it on the usersindex route. Child route's don't inherit params from their parent resources. Create a users route and it will be available there.
I am trying to build a masonry view of the top selling Items in a hypothetical eCommerce Site but Masonry is being rendered before the Data Models can be generated over RESTAdapter. Here are is my Ember.js code:
App.Userprofile = DS.Model.extend({
loggedIn: DS.attr('boolean'),
name: DS.attr('string'),
totalItems: DS.attr('number'),
});
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
this.store.find('userprofile', 'bat#man.com').then (function(userprofile) {
controller.set ('model', userprofile);
});
}
});
App.ApplicationAdapter = DS.DjangoRESTAdapter.extend({
host: HOST,
namespace: 'api'
});
App.ApplicationView = Ember.View.extend({
elementId: '',
classNames: ['container','fullwidth'],
templateName: 'application'
});
App.Cloud = DS.Model.extend({
item: DS.attr('string'),
numberItems: DS.attr('number'),
rank: DS.attr('number')
});
App.CloudAdapter = DS.DjangoRESTAdapter.extend({
host: HOST,
namespace: 'api',
});
App.CloudController = Ember.ObjectController.extend({
needs: ['application'],
cloudSize: function() { // Determines the size of the div
var cloudsize = Math.round (this.get('model.numberItems') * 5 / this.get('controllers.application.totalItems')) + 1;
var divName = "score" + cloudsize.toString();
return divName;
}.property('model.numberItems', 'controllers.application.totalitems')
});
App.ItemcloudRoute = Ember.Route.extend({
setupController: function(controller) {
this.store.findAll('cloud').then (function(itemcloud) {
controller.set ('model', itemcloud);
});
}
});
App.ItemcloudController = Ember.ArrayController.extend({
needs: ['cloud', 'application'],
sortProperties: ['rank'],
});
App.ItemcloudView = Ember.View.extend({
elementId: 'magicgrid',
classNames: ['cloudcontainer'],
templateName: 'itemcloud',
didInsertElement: (function() {
this._super();
Ember.run.scheduleOnce('afterRender', this, this.applyMasonry);
}).observes('controller.itemcloud'),
applyMasonry: function() {
setTimeout( function() { // settimeout to ensure masonry is called after data models are generate
console.log ("applyMasonry being called");
$('#magicgrid').masonry({
itemSelector: '.company',
isAnimated: true
});
}, 2000);
}
});
Here is the portion of the template file where itemcloud is generated.
<script type="text/x-handlebars" data-template-name='itemcloud'>
{{#each controller.model itemController="cloud"}}
<div {{bind-attr class=":company cloudSize"}}>
<div class="companylogo">
<img src="images/logos/color-logos/logo-01.jpg" />
</div>
<div class="count">{{numberItems}}</div>
</div>
{{/each}}
<div class="clearfix"></div>
</script>
Now, I am struggling to find a way to hold the Masonry rendering until after the data is fetched due to the asynchronous nature of the data fetching and the template rendering. My research says that using a View for the CloudController Objects would be useful, but am trying to figure out if there is something I am missing in my current design. Also, if someone can provide pointers to use Views correctly here for the CloudController Objects
Let me know if I need to provide any more clarifications. Thanks!
if you doing it in the setupController Ember assumes the model is already ready and continues rendering the page despite the response not coming back from the server.
The easiest way to do it is to return your model/promise in the model hook. Ember will wait on rendering the page until the model has been resolved.
App.ItemcloudRoute = Ember.Route.extend({
model: function(){
this.store.find('cloud');
}
});
The code above will do the same thing your code was doing, except Ember will wait for the find to resolve before creating and setting the model on the controller.
As per kingpin2k comments updating the answer to reflect the working code:
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return this.store.find ('userprofile', 'bat#man.com');
},
setupController: function(controller, model) {
controller.set ('model', model);
}
});
I have a simple app on fiddle http://jsfiddle.net/kitsunde/qzj2n/2/
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" id="profile">
Profile Page
{{ email }}
</script>
Where I'm trying to display a profile page.
window.App = Ember.Application.create();
App.Router.map(function () {
this.resource('profile', {path: '/'});
});
App.User = DS.Model.extend({
email: DS.attr('string')
});
App.User.FIXTURES = [
{
id: 1,
email: 'herpyderp#gmail.com'
}
];
App.ProfileRoute = Ember.Route.extend({
model: function(){
return App.User.find().get('firstObject');
}
});
But I'm getting an exception:
Error while loading route: TypeError: undefined is not a function
What am I missing?
There are a few things missing. You can find the fixed fiddle here:
http://jsfiddle.net/47cHy/
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter;
App.Router.map(function () {
this.resource('profile', { path: '/' });
});
App.User = DS.Model.extend({
email: DS.attr('string')
});
App.User.FIXTURES = [
{
id: 1,
email: 'herpyderp#gmail.com'
}
];
App.ProfileRoute = Ember.Route.extend({
model: function() {
return this.store.find('user').then(function(users) {
return users.get('firstObject');
});
}
});
Your template had the id index and not the name of the route profile
You have to tell Ember specifically to use the fixture adapter.
You accessed the model directly via the global object. You should let Ember do the work via the internal resolver and use this.store.find.
.find() returns a promise. You should get the first object in the then handler and return it there.
In my application i have model and i want when model update then send an ajax Request to server. for example i have a model like this :
App.Post = DS.Model.extend({
title:DS.attr('string'),
comment:DS.attr('string')
});
And controllers like this :
App.PostController = Ember.Controller.extend({
//if post model update send Ajax Request
});
App.CommentController = Ember.Controller.extend({
//if post model update send ajax Request
});
App.OtherController = Ember.Controller.extend({
//if post model update send ajax Request
});
You can define a action in the route
App.ApplicationRoute = Ember.Route.extend({
actions:{
sendRequest:function(){
//send Ajax Request
}
}
});
and in the setupController hook of your post route you subscribe to model events
App.PostRoute = Ember.Route.extend({
setupController: function(controller, model) {
controller.set('model', model);
model.on('didUpdate',controller,function(){this.send('sendRequest')})
model.on('didCreate',controller,function(){this.send('sendRequest')})
model.on('didDelete',controller,function(){this.send('sendRequest')})
}
});
hope this help, it's only an example, you can do it in several ways, the idea is to subscribe to model events that fire when the server respond to POST, PUT or DELETE requests
based on your JsBin....
OlapApp.OlapRoute = Ember.Route.extend({
setupController(controller,model){
var that = this;
this.store.findAll('axisModel').then(function(axisModel){
axisModel.on('didUpdate',controller,function(){this.send('sendRequest')})
axisModel.on('didCreate',controller,function(){this.send('sendRequest')})
axisModel.on('didDelete',controller,function(){this.send('sendRequest')})
that.controllerFor('OlapColumn').set('model', axisModel);
that.controllerFor('OlapRow').set('model', axisModel);
that.controllerFor('OlapFilter').set('model', axisModel);
});
}
});
Ember shows me the following error: Uncaught Error: No route matched the URL '/users'
Sks.IndexRoute = Ember.Route.extend
redirect: ->
this.transitionTo 'users'
Sks.Router.map ->
this.resource 'users', path: 'users/:user_id'
Sks.UsersRoute = Ember.Route.extend
setupController: (controller, model) ->
this.controllerFor('users').set 'content', Sks.User.find()
this.controllerFor('currentUser').set 'content', Sks.CurrentUser.find 1
this.controllerFor('top').set 'content', Sks.Top.find()
this.controllerFor('hamsters').set 'content', Sks.Hamster.find()
Everything works when I remove the dynamic segment.
Version: v1.0.0-rc.1-78-gd4e6a5c
edit#1
added IndexRoute
In Ember, collections and items actually use separate routes. Here's how I do it:
App.Router.map(function () {
this.resource('contacts', { path: '/contacts' });
this.resource('contact', { path: '/contact/:contact_id' });
});
App.IndexRoute = Ember.Route.extend({
redirect: function () {
this.replaceWith('contacts');
}
});
App.ContactsRoute = Ember.Route.extend({
model: function (params) {
return App.Contact.find();
}
});
App.ContactRoute = Ember.Route.extend({
model: function (params) {
return App.Contact.find(params.contact_id);
}
});
Here's a working jsFiddle.
It seems that I should have RTM :)
Sks.Router.map ->
this.resource 'users', ->
this.resource 'user', path: ':user_id'