Ember - Bind fail when transition back to login view - ember.js

When i first go the my login url, the inputs are correctly binded to the properties on my controller.
Then a press logout and what it does is transition back to the login page.
When i try to login again, it fails, because the input values arent binded to the controller, additionally i get this error:
Uncaught Error: Assertion Failed: Attempted to register a view with an id already in use: login
If i refresh the page it works.
Some of my code for references:
LoginRoute
export
default Ember.Route.extend({
setupController: function(controller) {
controller.reset();
},
beforeModel: function() {
if (!Ember.isEmpty(this.controllerFor('sessions.login').get('token'))) {
this.transitionTo('promotions');
}
}
});
LogoutRoute
export
default Ember.Route.extend({
beforeModel: function() {
this.controllerFor('sessions.login').reset();
this.transitionTo('sessions.login');
}
});
LoginAction on Controller
loginUser: function() {
var _this = this;
var login = this.get("login");
var pass = this.get("password");
Login Form
<form role="form" {{action 'loginUser' on='submit'}}>
<div class="form-group">
{{input type="text" class="form-control" id="login" placeholder="Login" value=login autofocus="autofocus"}}
{{input type="password" class="form-control" id="password" placeholder="Password" value=password}}
</div>
<div class="form-group">
<span class="input-group-btn">
<button class="btn btn-default" type="submit" ><span>Entrar</span></button>
</span>
</div>
</form>
After testing some more, i saw that the textFields are duplicating when i transition back to this page.
I really can't figure out, why

Related

Fire form submit event from custom component

I'm using the latest Ember (3.2).
I have made extension of text-area component:
app/components/enterable-textarea.js
export default TextArea.extend({
keyPress(event) {
if (event.keyCode === 13) {
console.info('e ', event);
}
}
});
I see the debug output in the console once I hit the 'Enter' key.
In my route template I have simple form like:
<form {{action "save" model.newNote on='submit'}}>
<div class="form-group">
<label for="tag">Tag</label>
{{input type="text" value=model.newNote.tag
placeholder="#anytag" class="form-control"}}
</div>
<div class="form-group">
<label for="note">Notepad</label>
{{enterable-textarea value=model.newNote.note
rows="6" class="form-control"}}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Ho do I pass form action to the component or fire the 'submit' event of the form?
I need to pass whole form to the route action by pressing the 'Enter'
You pass an action as a property and then call it as a function:
export default TextArea.extend({
onEnter: () => {}, //or function() {},
keyPress(event) {
if (event.keyCode === 13) {
this.get('onEnter')(); //or even this.onEnter();
}
}
});
{{enterable-textarea value=model.newNote.note
rows="6" class="form-control" onEnter=(action "save" model.newNote)}}
Read more about actions

Loading data that isnt on the route?

I have a dropdown setup on a form but how do i set it up if my data isnt in the route? I am trying to load in a list of territories on a new dealer form. I have added ember-power-select add on but I cant figure out how to load the data to the add on to display the available options. Do I need to create a service or controller?
New to ember just trying to work through the basics.
Router.map(function() {
this.route('login');
this.route('admin', function() {
this.route('territory', function() {
this.route('new');
this.route('edit', { path: '/:territory_id/edit'});
this.route('view', { path: '/:territory_id/view'});
});
this.route('dealer', function() {
this.route('view', { path: '/:dealer_id/view'});
this.route('new');
});
});
});
This is my form I am using on creating a new item.
<div class="well">
<form class="form-horizontal">
<fieldset>
<legend>New Dealer</legend>
<div class="form-group">
<label for="inputFirstName" class="col-lg-2 control-label">Name</label>
<div class="col-lg-4">
{{input type="text" value=model.dealerName class="form-control" placeholder="Dealer Name"}}
</div>
</div>
<div class="form-group">
<label for="inputFirstName" class="col-lg-2 control-label">Territory</label>
<div class="col-lg-4">
{{#power-select selected=dealer options=dealer onchange=(action "chooseDestination") as |dealer|}}
{{dealer.dealerName}}
{{/power-select}}
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
{{#link-to 'admin.dealer' class="btn btn-default"}}Cancel{{/link-to}}
<button type="submit" class="btn btn-primary" {{action 'saveDealer' model}}>Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
Just because a route is the new action for a territory or the view action for a dealer, doesn't mean that you can't load other data there.
For example, in the territory/view route, you could load all the dealers.
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return Ember.RSVP.hash({
territory: this.store.find('territory', params.territory_id),
dealers: this.store.findAll('dealer')
})
}
});
Then in your controller and templates, you would have access to model.territory and model.dealers

updating template with response in Ember after create/update action

I am working on a simple CRUD app using ember js. I have a template with a input form which sends data to the server and server responds with success response.
input form data: "user": {"id": 1, "name": "John"};
server response: {"message":"Created successfully", "nextId": 2}.
I want to display the success message on the same template(one with the input form). Because template refers to the user model and user model does not have a message attribute. How can it be done? Please help.
Here is my code:
var Manager = Ember.Application.create();
Manager.Router.map(function() {
this.resource('users');
this.resource('user', {path: '/users/:user_id'});
this.resource('home', {path: '/'});
});
Manager.UserRoute = Ember.Route.extend({
model: function(params) {
return jQuery.getJSON("http://localhost:8085/users/"+ params.user_id);
},
actions :{
insert : function(){
var user = this.modelFor("User");
$.ajax({
url: "http://localhost:8085/Users",
data: JSON.stringify(user),
type: "POST",
contentType: "application/json",
})
.done(function(data){
//set data.message to display on UI
})
}
}
});
and my template looks like this:
<script type="text/x-handlebars" data-template-name="user">
<form class="form-horizontal" role="form" {{action "insert" on="submit"}}>
<div class="form-group">
<label for="userId" class="control-label col-xs-2">User Id</label>
<div class="col-xs-4 input-group">
{{input type="number" value=_id class="form-control" id="userId" placeholder="Identity"}}
</div>
</div>
<div class="form-group">
<label for="name" class="control-label col-xs-2">Name</label>
<div class="col-xs-4 input-group">
{{input type="text" value=name class="form-control" id="name" placeholder="Name"}}
</div>
</div>
{{#if message}}
<div class="alert alert-success input-group" role="alert">{{message}}</div>
{{/if}}
<div class="form-group button-center">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
</script>
Set the message property on your controller to the response that comes back.
actions :{
insert : function(){
var user = this.modelFor("User");
var self = this;
$.ajax({
url: "http://localhost:8085/Users",
data: JSON.stringify(user),
type: "POST",
contentType: "application/json",
})
.done(function(data){
//set data.message to display on UI
self.controllerFor('user').set('message', data.message);
})
}
}

Using {{render}} to display a form and save a model instance from anywhere in the application

I have a resource (Trip) and its routes - trips.index, trips.edit, trips.new. I would like to put a copy of the form in trips/new into application.hbs template so it appears on every page.
The form in trips/new route works but the one in application.hbs doesn't. I get the following errors when I submit the form:
Uncaught Error: Assertion Failed: Cannot delegate set('name', a) to
the 'content' property of object proxy
: its 'content' is
undefined.
Uncaught Error: Assertion Failed: Cannot delegate set('errorMessage',
You have to fill all the fields) to the 'content' property of object
proxy : its 'content' is
undefined.
I have the following code.
application.hbs:
...
{{render "trips/new"}}
...
{{outlet}}
...
templates/trips/new.hbs:
<form {{action "save" on="submit"}} role="form">
<p class="text-danger">{{errorMessage}}</p>
<div class="form-group">
<label for="">Name</label>
{{input class="form-control" value=name}}
</div>
<div class="form-group">
<label for="">Country</label>
{{input class="form-control" value=country}}
</div>
<div class="form-group">
<label for="">Start Date</label>
{{input class="form-control" value=startDate placeholder="YYYY-MM-DD"}}
</div>
<div class="form-group">
<label for="">End Date</label>
{{input class="form-control" value=endDate placeholder="YYYY-MM-DD"}}
</div>
<input type="submit" value="Save" class="btn btn-primary">
<button {{action "cancel"}} class="btn btn-default">Cancel</button>
</form>
controllers/trips/base.js:
import Ember from 'ember';
export default Ember.ObjectController.extend({
isValid: Ember.computed(
'name',
'country',
function() {
return !Ember.isEmpty(this.get('name')) &&
!Ember.isEmpty(this.get('country'));
}
),
actions: {
save: function() {
if (this.get('isValid')) {
var _this = this;
this.get('model').save().then(function(trip) {
_this.transitionToRoute('trips.show', trip);
});
} else {
this.set('errorMessage', 'You have to fill all the fields');
}
},
cancel: function() {
return true;
}
}
});
controllers/trips/new.js:
import TripsBaseController from './base';
export default TripsBaseController.extend({
actions: {
cancel: function() {
this.transitionToRoute('trips.index');
return false;
}
}
});
routes/trips/new.js:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('trip');
},
actions: {
save: function() {
return true;
},
cancel: function() {
return true;
}
}
});
Any idea how I can solve this? I'm about to try converting it into a View or component but I'm wondering if I can still use {{render}} and I'm missing something simple here.
I'm using ember-cli with ember 1.7.0 and ember-data 1.0.0-beta.10.
I've also added a JS Bin here:
http://jsbin.com/zofive/edit
Here's the answer - I needed to set the model using the Application Route, setupController and controllerFor.
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function() {
this.controllerFor('trips/new').set('model', this.store.createRecord('trip'));
}
});
JS Bin (non-ES6): http://jsbin.com/zofive/13
Thanks to #locks, #abuiles and #xymbol.

Ember - displaying model value in form field

I have a user settings form like so:
<script type="text/x-handlebars" data-template-name="settings">
<form class="form-horizontal user-form" {{action "update" on="submit"}}>
<div>
<label>First Name</label>
{{input type="text" value=firstName placeholder="First Name"}}
{{error.firstName}}
</div>
<div>
<label>Last Name</label>
{{input type="text" value=lastName placeholder="Last Name"}}
{{error.lastName}}
</div>
<div>
<label>Email Address *</label>
{{input type="text" value=email placeholder="Email Address"}}
{{error.email}}
</div>
</form>
</script>
In my route for this page, I define the model:
App.SettingsRoute = Ember.Route.extend({
model: function() {
return this.store.find('user', 1);
}
});
If things are left like this, the form will automatically populate with the values retrieved from the model. However, if I add a controller:
App.SettingsController = Ember.Controller.extend({
actions: {
update: function() {
// Do something
}
}
});
...They won't. So how do I use my model in conjunction with this controller to set the properties?
The way you defined your controller was as a regular Ember.Controller and not an Ember.ObjectController so the controller is not proxying the model. If you modify it to be like this:
App.SettingsController = Ember.ObjectController.extend({
actions: {
update: function() {
// Do something
}
}
});
Then it should still automatically populate with the values from the model.