My template is rendering data OK without any problem, but if I try to access to it inside my JS script i get null or undefined... Here is my code
iron-router
#route 'responder',
path: '/quesabesde/:_screenName'
yieldTemplates:
responderContent:
to: "mainContent"
responderHeader:
to: "mainHeader"
waitOn: ->
#subscribe 'getPreguntas', #params._screenName
data: ->
Preguntas.findOne({owner: #params._screenName})
Template script with NULL result
Template.responderContent.rendered = ->
console.log(#data)
Template HTML WORKING
{{#each level}}
<h1>{{title}}</h1>
{{/each}}
And I get null on console... but as I said my template is rendering it OK. I want to access data inside my script in order to set sessions and manipulate the data for other purposes
This is a documented (if often undesirable) phenomenon. I would highly recommend reading this, particularly from Nov 19 downwards. Note that the easiest fix is just to have a loading template.
Related
I am currently testing an angularjs directive. This directive has a templateUrl. I would lke to test the view to make sure it was initialized correctly i.e. correct number of buttons, certain elements hidden.
The problem I am having is that when I insert my html file into the template cache I still get :
"message": "Unexpected request: GET partials/stuff/stuff-leader.html
I assumed that when I used the templateCache I would no longer have to use:
$httpBackend.whenGET("partials/stuff/stuff-leader.html").respond([{
userId: 000
}]);
but this does not seem to be the case. I am wondering am I correctly inserting the template, here is how I am doing it:
template = $templateCache.get('/full/root/disk/path/to/file/stuff/stuff-leader.html');
$templateCache.put('/myApp/templates/stuff-leader.html',template);
Is this correct, or should I be placing it somewhere else?
Your normal template is looked for at /partials/stuff/stuff-leader.html, so this is what you need to inject into the template cache instead of /myApp/templates/stuff-leader.html.
You are performing a request with the $templateCache.get. Instead do:
beforeEach(inject(function ($templateCache) { $templateCache.put('partials/stuff/stuff-leader.html', '< div >...TemplateCode....< /div >'); }));
I am upgrading my
Emberjs => from 1.10.0 to 1.12.0
Ember-cli => from 0.1.12 to 0.2.5
While i am figuring out most of the deprecations there are few which i am not able to understand. PFB the same
DEPRECATION: Ember.required is deprecated as its behavior is inconsistent and unreliable. Where is this used and how to change it?
DEPRECATION: lookupFactory was called on a Registry. The
initializer API no longer receives a container, and you should use
an instanceInitializer to look up objects from the container.
I do understand this issue but my initializer does not use lookup at all. PFB the code of my initializer.
//app/initializer/abc
initialize: function(registry, app) {
app.register('store:main', Store);
// Inject into each route a store property with an instance of store:main
app.inject('route', 'store', 'store:main');
// Inject into each controller a store property with an instance of store:main
app.inject('controller', 'store', 'store:main');
}
//app/initializer/def
initialize: function(registry, app) {
// Register the session object.
app.register('session:main', Session);
// Inject the session object into all controllers.
app.inject('controller', 'session', 'session:main');
}
DEPRECATION: Using the context switching form of {{each}} is
deprecated. Please use the block param form ({{#each bar as
|foo|}}) instead. See
http://emberjs.com/guides/deprecations/#toc_more-consistent-handlebars-scope
for more details.
I understand here that {{#each foo in bar itemController="abc"}} should be changed to {{#each bar itemController="abc" as |foo|}}. But my code is as below and does not have "in", meaning using this context!
{{#each paged itemController="class.adm.man.stop-term"}}
How can i change this?
Following your list:
Seems like it's an ember-data related issue. If not, I'm sure there is another addon which use it, but not you. Thus nothing you can do.
The same thing. I've already introduced an example as a comment. You code looks good for me, so, I believe, nothing you can do there as well.
Ember tries to make more consistent and explicit scopes. in part is not deprecated for now, so the simplest solution is to add dummy in part, for example {{#each page in paged itemController="class.adm.man.stop-term"}}. But in general I'd recommend to use more complex solution - to create an ItemList component and refactor it as:
{{#each paged as |page|}}
{{item-list model=page}}
{{/each}}
While running through the starter tutorial on EmberJS' site, a few things have me a little confused now.
One thing to note immediately is that I decided to use the ember 1.9.0beta4 with handlebars 2.0.0 instead of 1.8.1 / 1.3.0 included in the starter pack.
First the code included in the screencast:
app.js
App.Router.map(function() {
this.resource('about');
this.resource('posts');
this.resource('post', {path: ':post_id'})
});
App.PostsRoute = Ember.Route.extend({
model: function() {
return posts;
}
});
and
index.html
{{#each model}}
<tr><td>
{{#link-to 'post' this}}
{{title}} <small class='muted'>by {{author.name}}</small>
{{/link-to}}
</td></tr>
{{/each}}
This works exactly as expected and the requested post appears when clicked.
However, because I'm using 1.9.0, the preceding code produces a deprecated warning for {{#each}}, telling me to use {{#each foo in bar}} instead. I understand why this appears and agree the verbosity helps show exactly what data is being looped through.
So I change the line {{#each model}} to {{#each post in model}} and every bit of data disappears... I then try to change the code to:
updated index.html
{{#each post in model}}
<tr><td>
{{#link-to 'post' this}}
{{post.title}} <small class='muted'>by {{post.author.name}}</small>
{{/link-to}}
</td></tr>
{{/each}}
Great! The title and author's name once again appear for each post. But clicking either post gives me an undefined id. I change {{#link-to 'post' this}} to {{#link-to 'post' this.id}}. Same result. I change it to {{#link-to 'post' post.id}}. The id is now included but when I click the link I get this error:
Error while processing route: post Assertion Failed: You used the dynamic segment
post_id in your route post, but App.Post did not exist and you did not override
your route's `model` hook.
My questions are:
What happens internally that forces the post. prefix if I simply include the post in code? To me I should be able to use either this or continue to not need any prefix.
After adding post in to the each statement, what happens to this? Why does it no longer refer to the same object?
How can models be named to make it easier to categorize? post in model should really be post in posts but I haven't found a way to name the data container.
What is causing the error now that I'm no longer referring to the model as this? How can it be remedied?
Your frustration and questions are exactly the reason why the first syntax is deprecated and only the each post in ... form will be supported. Hopefully this answers your questions, and please respond if you need clarification.
In your first example where you use each model, the scope of the block changes to a post, meaning this refers to the current post in the loop. When you the form each post in ..., the scope does not change. When it does not change, that means this is actually referring to the previous scope (prior to the loop). In your example, the previous scope is the array controller, not the post object.
This is related to question 1. With the each post in ... format, this refers to whatever it was outside of the each block. It's not that something happens to this, it's that something does not happen to this because the scope doesn't change.
For better naming I usually setup a property as an alias to the content in the array controller:
posts: Ember.computed.alias('content')
In your original example, when you supply the link-to helper with this, you're passing the full post object. From what you've tried, it looks like this is the one thing you didn't do:
{#link-to 'post' post}}
I will try to answer your questions in order:
When you say {{#each model}} you are looping through the posts (array) in the model, so every time through the loop this is referring to the current post. Therefore when you say {{title}} you are really saying {{this.title}} When you are more explicit by saying {{#each post in model}} then each iteration through the loop is no longer referring to this and instead refers to the variable you made called post
Like mentioned in #1 above, this no longer refers to each individual iteration. I understand how you are thinking that perhaps still being able to use this (alongside post) would be convenient, but think about the following scenario. What happens when you have a nested {{#each}}? Would the implicit this refer to the outer array or inner array? If you really don't feel like typing the extra post. you can always use the {{#with post}} handlebars helper that scopes post back to this See the following example here
If you have a property in your model or controller, you can absolutely loop through that property as in {{#each color in colors}} See here for a working example
Finally, the link-to should be {{#link-to 'post' post}}
To the handlebars (version 1.0.0-rc.3) template I am passing two variables , one is the json and the other one is the string containing the current language on site.
self.template = template({ data: self.model, lang:self.lang });
Then inside the template file I have the following structure:
{{#each data}}
//this is working
{{../lang}}
{{#if this.title}}
{{this.desc}}
//i've tried this
{{../lang}}
//and this
{{lang}}
{{/if}}
{{/each}}
...but I couldn't access the lang value inside the if statement. What am I doing wrong?
I know you already solved your issue with a workaround but registering a Helper for doing a native way is cumbersome.
The thing is that every Handlebars helper overwrites the context and nest the new one inside the parent one, so you have to go up uone step further, like a UNIX like directory.
So, to access lang inside an each->if you have to use:
{{ ../../lang }}
I've find a solution by creating a handlebars helper function:
Handlebars.registerHelper('language', function() {
return self.lang; });
Then in the template i could use {{language}}
where ever I want.
I have an Ember.js app that gets its data from a JSON resource, and puts it into an ember-data model (Not sure about the terminology) for use in a Handlebars.js view. When I try to put the data into the template context, I get this error:
TypeError: arrangedContent.addArrayObserver is not a function
I've made a Fiddle to demonstrate it. Use the actual Fiddle to view the code, use the following link to see the error (which makes it try to put data into the template/view):
http://fiddle.jshell.net/WZ4vt/show/#/item/1
s = App.store.find(App.Item, 1);
s.get('value1');
The above works fine, and returns "test".
I updated the fiddle: http://jsfiddle.net/WZ4vt/3/
Your mistake was to declare your ItemController as ArrayController, but your Data Store just returned a single entity. I fixed that and additionally your Handlebars Template, as this was not working either.
So this is the new controller declaration:
ItemController: Em.Controller.extend(),
And the updated Template:
<script type="text/x-handlebars" data-template-name="item">
{{content.value1}}
{{content.value2}}
</script>
Here the working link: http://fiddle.jshell.net/WZ4vt/3/show/#/item/1