Error while using simple login in ember? - ember.js

I am a newbie to Ember and as a part of learning i was trying to set up the login form from one tutorial but it doesnot seem to be working.
Error: Invalid Path---Thats the Error i am getting in login method
I want to see if the password is okay then connect login template else kick the user to '/'.?
Html file
<script type="text/x-handlebars" data-template-name="login">
{{message}} <br>
E-Mail {{view Ember.TextField target="controller" valueBinding= controller.email}} <br />
Password {{view Ember.TextField target="controller" valueBinding= controller.password}} <br />
<button {{action login}}>Login</button>
</script>
<script type="text/x-handlebars" data-template-name="loggedin">
Welcome to Our Site !
</script>
JS File
App.LoginController = Ember.ObjectController.extend({
email :null,
password :null,
message :null,
login : function() {
var loginCreds = this.getProperties('email','password');
if (loginCreds.password === 'admin') {
this.set('isAuthenticated',true);
console.log(isAuthenticated);
this.get('target').send('isAuthenticated');
}
else{
this.set('message','Invalid password');
this.set('isAuthenticated',false);
console.log(isAuthenticated);
this.get('target').send('isAuthenticated');
}
}
});
App.LoginRoute = Ember.Route.extend({
isAuthenticated : function(router) {
router.transitionTo('loggedin');
},
connectOutlets: function(router) {
if (!router.get('loginController.isAuthenticated')) {
router.transitionTo('/');
}
router.get('loginController').connectOutlet('loggedin');
},
});

i think problem may be u didnt map the path u are giving in the browser.You should map the path like this
App.Router.map(function () {
this.route('login');
});
then in the url u can add #login

Related

How to dynamically generate clickable links in ember using handlebars

I am trying to generate click able links using emberjs framework. I have the model setup correctly and I have the following handlebar template:
<script type="text/x-handlebars" data-template-name="index" >
{{#each name in model.mymodules }}
{{#link-to name 'home' }}{{name}}{{/link-to}}
{{/each
</script>
The idea is to call modulename/home on each link.
For ex: say I have 3 modules: "abc", "xyz", "123"
I want three links:
abc <a href="/abc/home">, xyz <a href="/xyz/home">, 123 <a href="/123/home">
What controller/route do I need to define for this to work.
jsfiddle:
http://jsfiddle.net/spkRa/2/
You need to make use of ember resources for dealing with this problem
Read http://emberjs.com/guides/routing/defining-your-routes/
Example of application code should be something like this. JSfidle http://jsfiddle.net/NQKvy/291/
App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true
});
App.Router.map(function() {
this.resource('modules', { path: '/modules' }, function() {
this.route('home', {path: ':module_name/home'});
});
});
App.IndexRoute = Ember.Route.extend({
model:function(){
return App.Modules;
}
});
App.ModulesHomeRoute = Ember.Route.extend({
model: function(params) {
//returns an object from an ember array based on the property value
return App.Module.findProperty('name',params.module_name);
},
serialize: function(model, params) {
//updates the url with the param value
return { module_name: model.get('name') };
}
});
App.Modules = Ember.A([
Ember.Object.create({name:'aaa'}),
Ember.Object.create({name:'bbb'}),
Ember.Object.create({name:'ccc'})
]);
And hadlebars code
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each}}
<li>{{name}}</li>
<li>{{#link-to 'modules.home' this}}{{name}}{{/link-to}}</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="modules/home">
This is the home of the module {{name}}
</script>

Why does Action event on a button does not call the controller function

I have an index.html file which has a button with an action handler.
<button {{action 'modules'}} > press </button>
But nothing happens when I press the button.
please look at the code at jsbin:
http://jsbin.com/OREMORe/1/edit
Feel free to correct any other inconsistencies.
Appreciate any help. Thx.
You'd do it like this. Please note that there were a few things wrong with your code:
1) You handlebars code with your button in it was not wrapped in a handlebars script tag
2) You're 'modules' template was in the application template
3) You did not include valid links to the necessary libraries
4) There was not rootElement specified for the Application
5) You tried to access ModulesController in the ApplicationRoute. I inserted a redirect to 'modules'
6) You tried to access module in your {{#each}} loop, but that does not exists in your model. What you want is content.
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="modules">
<ul>
{{#each content}}
<li>{{this}}</li>
{{/each}}
<button {{action 'modules'}} > press </button>
</ul>
</script>
And:
var Test1 = Ember.Application.create({
rootElement: 'body',
ready: function() {
console.log("App ready1");
}
});
Test1.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('modules');
}
});
Test1.Router.map( function() {
this.route('modules');
});
Test1.ModulesController = Ember.Controller.extend({
actions: {
modules: function() {
console.log('clicked the button');
/* this.transitionToRoute('modules');*/
}
}
});
Test1.ModulesRoute = Ember.Route.extend({
model: function() {
return ['item1', 'item2'];
}
});

Using the new Ember RouterV2, how do you immediately redirect to another state from the index state?

What I have so far:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function(match){
match('/').to('application');
match('/edit').to('edit');
});
App.ApplicationRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('edit');
},
events: {
startEdit: function( context ){
this.transitionTo( 'edit' );
}
}
})
App.EditRoute = Ember.Route.extend({
init: function(){
this._super()
console.log('EditRoute')
},
});
Handlebars:
<script type="text/x-handlebars" data-template-name = 'application'>
Hello World
{{ outlet main }}
</script>
<script type="text/x-handlebars" data-template-name = 'edit'>
<div class = 'edit-background'> Edit State: {{ title }} </div>
</script>
I have four questions:
When I open the application it just remains in the home page, is the redirectTo hook suppose to immediately redirect you to another state?
In addition, I have this events hash in AplicationRoute per suggestion from here: How to programmatically transition between routes using Ember.js' new Router. but I read through the answers and still am not sure how you are supposed to use it.
How do I test the router on the console? before you could navigate between the states by calling transitionTo commands, what do I do now?
For some odd reason, my application template seem to rendered twice, as in there are two 'Hello World' up there, and when try to add something like: <li>{{#linkTo edit}}edit{{/linkTo}}</li>
I get this error:
'Uncaught TypeError: Cannot read property 'container' of undefined -- ember.js:2223'
This is how you would initially load the editView/route/template on application start up:
Router
App.Router.map(function(match){
match('/').to('application',function(match){
match('/').to('edit')
})
})
ApplicationTemplate
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
EditTemplate
<script type="text/x-handlebars" data-template-name="edit">
I am embedded!
</script>
EditRoute
EditRoute = Ember.Route.extend({
renderTemplates:function () {
this.render('edit', {
into:'application'
});
})

Toggle between child views with ember.js?

I am trying to render a view that toggles between two of its children (or so I'd hope) and something is not exactly working. Here is my template:
{{#view App.LoginFormView isVisibleBinding="user.isNotAuthenticated" }}
Username: {{view Ember.TextField valueBinding="user.loginName"}} /
Password: {{view Ember.TextField valueBinding="user.userPassword" type="password"}}
<button class="btn" {{ action "login" }} {{bindAttr disabled="user.isNotValid"}}>Login</button>
{{/view}}
{{#view App.LoginInfoView isVisibleBinding="user.isAuthenticated" }}
You are logged in as {{user.loginName}}. Click <a {{action "logout"}}>here</a> to logout
{{/view}}
in app.js I have the following:
App.User = Ember.Object.extend({
loginName:'',
userPassword:'',
rememberMe:true,
isNotValid:function(){
return (this.get("loginName") == '') || (this.get("userPassword") == '');
}.property('loginName', 'userPassword'),
isAuthenticated:false,
isNotAuthenticated:function(){
return !this.isAuthenticated;
}.property('isAuthenticated')
});
App.AuthenticationController = Ember.Controller.extend({
login:function() {
alert("loginName:"+this.user.get('loginName')+";\n"+
"userPassword:"+this.user.get('userPassword')+";\n"+
"rememberMe:"+this.user.get('rememberMe')+";\n");
this.user.isAuthenticated = true;
},
user:App.User.create()
});
App.AuthenticationView = Ember.View.extend({
templateName: 'authentication',
userBinding:"App.AuthenticationController.user"
});
App.LoginFormController = Ember.Controller.extend({
userBinding:"App.AuthenticationController.user"
});
App.LoginFormView = Ember.View.extend();
App.LoginInfoController = Ember.Controller.extend({
userBinding:"App.AuthenticationController.user"
});
App.LoginInfoView = Ember.View.extend();
App.Router = Ember.Router.extend({
enableLogging:true,
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function(router){
router.get('applicationController').connectOutlet('authentication','authentication');
},
login:function(router){
router.get('authenticationController').login();
}
})
})
});
The problem I am having is that the view does not toggle on the change of isAuthenticated property. I was under impression that would happen automagically and yet it does not. Any ideas on how to make this work? Or am I missing something fundamental (ember.js newbie here, so be gentle :-))
Cheers,
Alex.
You can implement user authentication in the following way:
In your template (for example in _header.hbs templates which is a partial for application.hbs)
{{#if needAuth}}
// login form goes here
<button {{action submitLogin}}>login</button>
{{else}}
<small {{action logout}}>logout</small>
{{/if}}
In application controller:
submitLogin: function () {
// do login stuff
// if login success
that.set('needAuth', false);
// else
that.set('needAuth', true);
});
DOM will update automatically. In other partial templates you can use {{#if needAuth}} as well.

EmberJS Router App: Views vs Controllers

I'm creating a router-based EmberJS app (strongly modelled on the excellent router guide). However, I'm quite muddled over what belongs in a view vs in a controller.
I totally get that {{action showFoo}} often indicates a state change and that the Router is the state machine for my app. But some of my actions don't fall into that category.
Here's an example from my actual code (html simplified but mustaches intact). I want to have a login form that works via ajax (i.e. the html form doesn't post directly to the server, it tells my ember app to attempt a login via json).
<form>
Email Name: {{view Ember.TextField valueBinding="email"}}
Password: {{view Ember.TextField valueBinding="password"}}
<button type="submit" {{ action logIn target="this" }}>Sign in</button>
</form>
The valueBindings are fields in my loginController but the logIn handler is in my view (because I couldn't figure out how to tell the template to call the controller). I feel like this is a weird distribution & I'm not sure what the right Ember approach is to this.
I don't think the router should be handling the action because requesting a login attempt isn't really a state change. The loginController feels like the right place to try the login. After a login response is received then that controller could trigger the state change.
I don't think the router should be handling the action because requesting a login attempt isn't really a state change.
I think that's exactly the case: attempting a login should transition to an authenticating state, where for example another click to "login" is ignored.
So IMHO this should be handled by the router. I'm thinking about something like this, see http://jsfiddle.net/pangratz666/97Uyh/:
Handlebars:
<script type="text/x-handlebars" >
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="login" >
<p class="info">{{message}}</p>
Login to view the admin area <br/>
Email: {{view Ember.TextField valueBinding="email" }} <br/>
Password: {{view Ember.TextField valueBinding="password" }} <br/>
<button {{action login}} >Login</button>
</script>
<script type="text/x-handlebars" data-template-name="authenticating" >
Communicating with server ...
</script>
<script type="text/x-handlebars" data-template-name="admin" >
Hello admin!
</script>
​
JavaScript:
App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
login: function() {
// reset message
this.set('message', null);
// get data from login form
var loginProps = this.getProperties('email', 'password');
// simulate communication with server
Ember.run.later(this, function() {
if (loginProps.password === 'admin') {
this.set('isAuthenticated', true);
this.get('target').send('isAuthenticated');
} else {
this.set('message', 'Invalid username or password');
this.set('isAuthenticated', false);
this.get('target').send('isNotAuthenticated');
}
}, 1000);
// inform target that authentication is in progress
this.get('target').send('authenticationInProgress');
},
logout: function() {
this.set('isAuthenticated', false);
}
});
App.ApplicationView = Ember.View.extend({
templateName: 'application'
});
App.LoginView = Ember.View.extend({
templateName: 'login'
});
App.AdminView = Ember.View.extend({
templateName: 'admin'
});
App.AuthenticatingView = Ember.View.extend({
templateName: 'authenticating'
});
App.Router = Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
loggedOut: Ember.Route.extend({
route: '/',
connectOutlets: function(router) {
router.get('applicationController').connectOutlet('login');
},
login: function(router) {
router.get('applicationController').login();
},
authenticationInProgress: function(router) {
router.transitionTo('authenticating');
}
}),
authenticating: Ember.State.extend({
enter: function(router) {
router.get('applicationController').connectOutlet('authenticating');
},
isAuthenticated: function(router) {
router.transitionTo('loggedIn');
},
isNotAuthenticated: function(router) {
router.transitionTo('loggedOut');
}
}),
loggedIn: Ember.Route.extend({
route: '/admin',
connectOutlets: function(router) {
if (!router.get('applicationController.isAuthenticated')) {
router.transitionTo('loggedOut');
}
router.get('applicationController').connectOutlet('admin');
},
logout: function(router) {
router.get('applicationController').logout();
}
})
})
})
});​
You can use the controller for this, the template your using have access to the controller.
<script type="text/x-handlebars" data-template-name="loginTemplate">
{{#if controller.login}}
Logged in!
{{else}}
Login failed
{{/if}}
</script>
This fiddle shows a small app, which does that: fiddle
Then after login has occured you can make an actioncall to your router, or show the user that login failed.
I have just made it done by change the codes as:
{{ action logIn target="controller" }}