I have something like the following in a template:
<div ng-if="foo">
...
</div>
<div ng-class="foo && 'foo-is-present'">
...
</div>
In the controller for this scope, I have the following:
$scope.foo = $resource("path/to/resource").query();
The resource loads just find and returns a simple JSON array (verified by watching request in Chrome), and other debugging shows that foo contains the array, exactly as it should. The second div applies the foo-is-present class as expected, however the first div still has its ng-if evaluating to false, preventing that div from rendering.
This doesn't seem right, as I want that first div to show up once the results of the resource have been loaded. What am I missing here?
EDIT It turns out ng-if's version of "truthy" does not include arrays, even if the array is not empty. I was able to work around this by adding turning the condition into ng-if="!!foo", but this feels hacky. If anyone has any better insight or solutions, please share!
Also in the Edit, above, but added as an answer so it is more immediately visible as a (hopefully) useful workaround.
It turns out ng-if's version of "truthy" does not include arrays, even if the array is not empty. I was able to work around this by adding turning the condition into ng-if="!!foo", but this feels hacky. If anyone has any better insight or solutions, please share!
What version of AngularJS are you using?
I'm using 1.2.10 and:
$scope.foo = [];
ng-if="foo"
Evaluates to true.
Perhaps the first div is not within the scope of the controller that contains foo?
Related
I can't figure out what I'm doing wrong here, but when I declare two components like this:
<todo-component [options]="selectOptions" [choice]="slideToggleSelection" (choiceChange)="handle($event)" group="weird">
</todo-component>
<todo-component [options]="selectOptions2" [choice]="slideToggleSelection2" (choiceChange)="handle($event)" group="test">
</todo-component>
... changing the value of one affects the value of the other. Check out this plunker for an example. -- for instance, selecting 'Y' in one actually selects them in both. I think I'm misunderstanding some fundamental concept but I'm banging my head against the wall on this one.
I think this is related to the [attr.name]="group". If you change it to [name]="group" it seems to work.
For some reason, this doesn't work at all.
{{user_slugged username}}
The {{username}} is a variable available to the template. However, it gives me a null / undefined value in the helper.
Here is my helper code
UI.registerHelper('user_slugged', function(username) {
... other stuff... return things.
}
The issue I am having is when I try something like this {{user_slugged 'Hello'}} it does everything right and returns what is expected.
However, when I try {{user_slugged username}} it doesn't seem to work even though I can easily display {{username}} in that same line of code.
Which seems really odd, now I'm thinking the way to send parameters to handlebars helpers might have changed in Meteor 0.8.0. If so, it'd be great if someone could point me into the right direction or give me an answer to this question.
EDIT: To clarify I am able to use {{username}} in the same line as {{user_slugged username}} so something like this works
{{username}}
username is an object property that is available in the template and at the point where I am trying to send it in as a param to the helper.
I am not sure why this is happening (maybe there is a global helper username?), but you should be able to fix it easily by writing
{{user_slugged ./username}}
instead of
{{user_slugged username}}
The dot always means the current data context, so there is no way that the rendering engine will get confused about it.
I'm trying to build a real watcher for a collection in my app and, at first, I thought that Angular would provide me everything I needed.
I mean, I had the $watch, both shallow and deep. and the $watchCollection, a $digest cycle that loops over my $scope-exposed variables through the dirty checking mechanic and triggers all the watchers...
Great! What else could I need?
Wrong!
Turns out that $watchCollection gets triggered only at the first change of the watched variable...
And that's it for the mighty watchers... why???
After a reality check, I realized that I needed some kind of horrible loop to check this collection, or else I had to implement some sort of callback to do this, whenever the var gets modified.
Anybody knows how this can be done in the cleanest way possible?
Important note:
I don't why, but it seems that some horrific bug in my code was gnawing my ankles...
Now that I've fixed it, both $watchCollection(expr, foo) and $watch(expr, foo, true) works as expected...
I was mislead by this SO post , in which an user comments:
[...] I don't see anything in your code that makes the subsequent requests (to check for new messages). Where does that happen?
I took his comments as proof of my hypothesis... my bad!
I'm leaving this question as a memento
I'm pretty sure a regular $watch will do this if you utilize the 3rd parameter (objectEquality). This will check if the objects are equal and not just references.
So, you can use something like this:
$scope.$watch('prop', function(value) {
// do something
}, true);
The true value tells Angular to compare objects instead of references.
The documentation for this feature is with scope.
below solution is bit of an hacking solution and should only be used if $watchCollection does not work. rather than watching on the array, watch on json
$scope.$watch(function() {
return angular.toJson($scope.array);
},
function() {
// watch logic
}
I am using above solution to watch on multiple arrays like below:
$scope.$watch(function() {
return JSON.stringify([$scope.array1, $scope.array2]);
},
function() {
// watch logic
}
you can user either of JSON.stringify or angular.toJson.
I am trying to bind a property of an object to a property that's bound in an ArrayController. I want all of this to occur after the object has already been created and added to the ArrayController.
Here is a fiddle with a simplified example of what I'm trying to achieve.
I am wondering if I'm having problems with scope - I've already tried to bind to the global path (i.e. 'App.objectTwoController.objectOne.param3') to set the binding to. I've also tried to bind directly to the objectOneController (which is not what I want to do, but tried it just to see if it worked) and that still didn't work.
Any ideas on what I'm doing incorrectly? Thanks in advance for taking the time to look at this post.
So in the example below (I simplified it a little bit, but same principles apply)... The method below ends up looking for "objectOne" on "objectTwo" instead of on the "objectTwoController".
var objectTwoController: Em.Object.create({
objectOneBinding: 'App.objectOne',
objectTwoBinding: 'App.objectTwo',
_onSomething: function() {
var objectTwo = this.get('objectTwo');
objectTwo.bind('param2', Em.Binding.from('objectOne.param3'));
}.observes('something')
});
The problem is that you can't bind between two none relative objects. If you look in the "connect" method in ember you will see that it only takes one reference object (this) in which to observe both paths (this is true for 9.8.1 from your example and the ember-pre-1.0 release).
You have few options (that I can think of at least).
First: You can tell the objects about each other and in turn the relative paths will start working. This will actually give "objectTwo" an object to reference when binding paths.
....
objectTwo.set('objectOne', this.get('objectOne');
....
Second: You could add your own observer/computed property that will just keep the two in sync (but it is a little more verbose). You might be able to pull off something really slick but it maybe difficult. Even go so far as writing your own binding (like Transforms) to allow you to bind two non-related objects as long as you have paths to both.
_param3: function(){
this.setPath('objectTwo.param2', this.getPath('objectOne.param3');
}.observes('objectOne.param3')
You can make these dynamically and not need to pre-define them...
Third: Simply make them global paths; "App.objectOneController.content.param3" should work as your binding "_from" path (but not sure how much this helps you in your real application, because with larger applications I personally don't like everything global).
EDIT: When setting the full paths. Make sure you wait until end of the current cycle before fetching the value because bindings don't always update until everything is flushed. Meaning, your alert message needs to be wrapped in Ember.run.next or you will not see the change.
if (1) {
google_conversion_value = 1;
}
What is the meaning of the above statement? I mean, this looks like it will always execute so why bother with the if statement?
updated: one reason might be remnants of scripting on the server side. Any other ideas?
updated2: could as easily change the value of the assignment without bothering with the if statement, no?
There are two likely explanations:
It's a leftover from debugging.
The file containing this code is generated dynamically and the original sourcecode contains something like if(<?php echo $some_stuff_enabled; ?>)
However, in the latter case it would have been cleaner to output that code block only if the condition is met - but maybe it's used in some crappy template engine that just allows replacements but no conditionals...
I've seen this before, and I've always assumed it was a remnant of some old condition that was no longer needed, but never removed. I can't see any actual reason to do something like that otherwise.
Potentially because the person writing the code wanted an easy way to turn it off and on again, this is especially useful if there is a lot of code inside the block (not the case here).
Another possibility is that the original programmer couldn't be bothered writing the logic or, more likely, it hadn't been specified so the "if" was left as a placeholder.
More than likely left in from a debug release or something similar. You're right, it will always execute. It could also have been done like this so that it can be easily enabled / disabled by setting the if to 0. Perhaps the developer intended to use it as a flag somewhere else in the code?
actually, this happens when the "if" condition is driven from server, so instead of doing the right thing and not produce the script when the condition is false, they do something like this:
if (<% if (my_server_condition) then Response.Write("1") else Response.Write("0") %>){
// code goes here
}
Perhaps the if statement used to check for a legitimate conditional, and then someone replaced it with a truthy value for testing/debugging/etc.
You're right, it will always execute because 1 is truthy. I would go through your source control history and investigate that line to see if it used to contain a real conditional. If the conditional was always 1, then it's likely a debugging statement. Otherwise someone might have meant for it to be a temporary change, and may not have meant to check that in (which could be bad).
I'm not sure where this code is from, but as you indicated it will always execute. As for why you'd do this, there are times where you want to see what the result of branch code would be, without having to setup an environment. In this case you can comment out the actual value and replace it with if(1) instead for testing:
// if( ... some hard to achieve condition )
if (1) {
// Now you can see what happens if this value is set quickly
google_conversion_value = 1;
}
Of course the problem with this is that it's sometimes easy to forget to remove the if(1) and uncomment the proper condition.
This is actually the javascript recommended by Google on http://support.google.com/adwords/bin/answer.py?hl=en&answer=1722054#nocomments (click on Step 2 for the sample HTML)