Angularjs 1.3 One Time Binding Not Always Working - angularjs

Looking at the documentation I'm supposed to prepend :: to the expression and it should remove itself. What I don't get is why it sometimes works and sometimes doesn't.
I've created a Plunker here that 80% of the time will run all the correct oneTime $$watchListener expressions (buttons should not work).
Yet sometimes in the Launch preview in full mode it doesn't fire and the buttons change the values.
I'm posting this because I just upgraded and they fail 100% of the time on my dev environment using the code below
<div class="user-location">
<span ng-if="::get.edit">
<span ng-if="::user.postal">
<span ng-bind="::user.postal"></span>
</span>
<span ng-if="::!user.postal">
<span>No postal</span>
</span>
Edit
</span>
<span ng-if="::!get.edit">
<span ng-bind="::user.postal"></span>
</span>
</div>
Anyone else have this issue or know of a sure fire way to trigger it?
Looking at the code:
// https://code.angularjs.org/1.3.0-beta.19/angular.js line 11404
if (!parsedExpression) {
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') { // Expressions get through here
oneTime = true;
exp = exp.substring(2);
}
...
if (parsedExpression.constant) {
parsedExpression.$$watchDelegate = constantWatchDelegate;
} else if (oneTime) {
parsedExpression.$$watchDelegate = parsedExpression.literal ? // Get through here as well but the
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate; // $$watchDelegate method never gets called
}
...

Related

value of progressbar doesnt work

theres my progress bar code:
<div class="col-sm-4" ng-repeat="var in payloadNbrMissionParStatut">
<h4 class="no-margin">{{var.number}}</h4>
<progressbar value={{tom}} class="progress-xs no-radius no-margin" type={{gg}} ng-if="var.des=='Clos' ? gg='danger' : var.des=='En cours'? gg='warning' :gg='info' " ></progressbar>
{{var.des}}
</div>
the problem is in the value: when i populate it with static data it works good, but when i populate wit data come from the controller it doesnt work.
var is a reserved JS keyword. As errors inside directive expressions are silent, you aren't seeing any alerts because it's simply being ignored. Change var to something else and it should work.

Strange behaviour with ng-bind angular

So wanted to have a spinning cube with pictures on, because that is what all the cool kids want. Then decided that I wanted to have it all in a database and use the mean stack, so set that up.
Here comes the problem. On the index.html version, the cube sometimes messes up and moves to the screen blocking everything else out. Just open the link below and click the menu a few different menu options a few time and you'll see what I mean.
http://v-ghost.port0.org:8081/TESTCube/public/index.html
Worked a long while trying to figure out what was wrong, and it turns out that it is related to how I load the menu, I tried to generate it using ng-bind-html.
<figure class="front"><div id="front-page" ng-bind-html="showpane('front')"></div></figure>
<figure class="back"><div id="front-page" ng-bind-html="showpane('back')"></div></figure>
<figure class="right"><div id="front-page" ng-bind-html="showpane('right')"></figure>
<figure class="left"><div id="front-page" ng-bind-html="showpane('left')"></figure>
<figure class="top"><div id="front-page" ng-bind-html="showpane('top')"></figure>
<figure class="bottom"><div id="front-page" ng-bind-html="showpane('bottom')"></figure>
Strangely, if I change this to just use text (i.e. less fancy way):
<button class="show-front">Front</button><br/>
<button class="show-back">Back</button><br/>
<button class="show-right">Right</button><br/>
<button class="show-left">Left</button><br/>
<button class="show-top">Top</button><br/>
<button class="show-bottom">Bottom</button><br/>
Try it on
http://v-ghost.port0.org:8081/TESTCube/public/index-nobind.html, unbreakable (famous last words).
What I can't understand is why, why does me calling a function in a button break the cubes path?
Also, is there an easier way to get the value of a string in an array then building a function to get it in a ng-bind?
Tried to make it as easy as possible to test around, should be just to copy the html if you want to give it a try.
After much fiddling about I never manage to figure out why ng-bind behaved like this. And without a error message it was pretty hard to identify the problem.
If you have the same problem, one way to get around it is to just change the controller to present the data under an object. So start by defining the controller as app
<body ng-app="DBFScube" ng-controller="AppCtrl as app">
Then call a sub function (getmenuname) for each option.
<button class="show-front">{{app.getmenuname('front')}}</button><br/>
<button class="show-back">{{app.getmenuname('back')}}</button><br/>
<button class="show-right">{{app.getmenuname('right')}}</button><br/>
<button class="show-left">{{app.getmenuname('left')}}</button><br/>
<button class="show-top">{{app.getmenuname('top')}}</button><br/>
<button class="show-bottom">{{app.getmenuname('bottom')}}</button>
The controller looks like this
var app = this;
//
//$http.get("http://localhost:3000").success(function(CubeSides){
// app.CubeSides = CubeSides;
//})
$http.get("http://localhost:3000").success(function(CubeSides){
$scope.sides=CubeSides;
console.log("Loading data");
})
app.getmenuname = function(side) {
if($scope.sides === undefined) {
console.log("Not loaded fside " + side );
} else {
console.log("Got menu pane " + $scope.sides);
var fside = $filter('filter')($scope.sides, function (d) {return d.side === side;})[0];
console.log("Sending: " + fside.menuname);
return fside.menuname;
}
}
This probably isn't the right way of doing it, but if all you need to do is set the name on some buttons, it does the trick:)

Soundmanager 2 not works with angular js "ng-repeat" directive

i`m busy on a music store web application with JAVA for back-end and Angular JS/HTML5/CSS3 for front-end.
ammm, and for music play back i used Sound Manager Java Script Library, all thing work fine with static 360 player, but when i try to use sound manager in ng-repeat directive, that not works, any suggestion please ? and is sound manager works with live dom elements created by angular js "ng-repeat" ?
Sound Manager Init
// init Sound Manager
soundManager.setup({
// path to directory containing SM2 SWF
url: 'player/'
});
threeSixtyPlayer.config.scaleFont = (navigator.userAgent.match(/msie/i)?false:true);
threeSixtyPlayer.config.showHMSTime = true;
// enable some spectrum stuffs
threeSixtyPlayer.config.useWaveformData = true;
threeSixtyPlayer.config.useEQData = true;
// enable this in SM2 as well, as needed
if (threeSixtyPlayer.config.useWaveformData) {
soundManager.flash9Options.useWaveformData = true;
}
if (threeSixtyPlayer.config.useEQData) {
soundManager.flash9Options.useEQData = true;
}
if (threeSixtyPlayer.config.usePeakData) {
soundManager.flash9Options.usePeakData = true;
}
if (threeSixtyPlayer.config.useWaveformData || threeSixtyPlayer.flash9Options.useEQData || threeSixtyPlayer.flash9Options.usePeakData) {
// even if HTML5 supports MP3, prefer flash so the visualization features can be used.
soundManager.preferFlash = true;
}
Angular ng-repeat
<div class="mod-contents">
<div class="questions-block" ng-repeat="question in filtered = ( questionList | filter:searchKey | orderBy : predicate : reverse)">
<div class="col-xs-12 col-sm-4 col-md-3 pull-right">
<div class="thumbnail block-black ">
<h3 class="block-title rtl-element">{{ question.description }}<span class="text-muted"> ({{ question.cat_code }}) </span></h3>
<div class="ui360 ui360-vis player-wrapper-md player-md "></div>
</div>
</div>
</div>
</div>
I was having the same problem. I think I know why it's happening. I believe in the javascript for sound manager it looks for instances of a sound manager player and doesn't find any. The ng-repeat section is not static; it can change. So when you load the page and the sound manager loads, the ng-repeat section does not yet contain any elements. Therefore sound manager decides not to add an event handler for checking if you click on the button.
I edited the mp3-player-button.js and in the init section I commented out where it said "if (foundItems>0)" so that it always adds the sound manager event handler.
This solution is a little hacky - so maybe you can implement something smarter. But it works for me. Hope it Helps!

The array model is not binding correctly to the view

I'm having problem to make my angularjs app model bind correctly to the view.
I have this methods in the controller to enable/disable the editing of the informations of a single marketplace:
$scope.shopEditing = function (marketplaceId) {
if ( ! $scope.settings) {
return false;
}
return $scope.shopEditingRegistry[marketplaceId];
};
$scope.toggleShopEditing = function (marketplaceId) {
if ( ! $scope.settings) {
return;
}
$scope.shopEditingRegistry[marketplaceId] = ! $scope.shopEditingRegistry[marketplaceId];
};
Then there's the piece of view that should be hidden when the editing for the specific marketplace is enabled:
<div ng-repeat="shopInformations in settings.shops.list">
<div class="line" ng-hide="{{shopInformations.isShopConnected || shopEditing(shopInformations.marketplaceId)}}">
{{marketplaceName(shopInformations.marketplaceId)}} shop not connected
<a class="button buttonGrayThin" ng-click="toggleShopEditing(shopInformations.marketplaceId)">Add</a>
</div>
</div>
The problem is that when I click on the button that is connected to toggleShopEditing(), the model is updated successfully, the shopEditing() is called correctly, but the view is not refreshed correctly.
The 'div class="line" ' is not being hidden.
I'm getting crazy. Any idea why this is happening?
Thanks a lot!
As suggested by #charlietfl it was enough to remove the {{ }} within ng-hide.

How to compare current time with JSON data

I have JSON data as below:
[
{
"morning":"5:36 am",
"evening":"7:00 pm"
}
]
I want to compare JSON data with current time. Ex: is morning > current time ?
HTML:
<div ng-repeat="item in schedule">
<div>Morning - {{item.morning}}</div>
<div>Eveing - {{item.evening}}</div>
</div>
I have specified the AngularJS part to display the Data and It's working. Now I want to compare the {{item.morning}} with current time and display a message in front of {{item.morning}} as "Time up" based on condition.
Please let me know how can I compare time in AngularJS. Thanks in advance.
As #PWKad mentioned, you should use a date library like moment.js.
One reason for that, might be that trying to implement it yourself can end with an ugly, quick-and-(really)-diry code like this:
Controller:
$scope.isTimeUp = function(time) {
var hour, minute;
if(time.split(" ")[1] == 'pm' && time.split(":")[0] != '12') {
hour = parseInt(time.split(":")[0]) + 12;
} else {
hour = parseInt(time.split(":")[0]);
}
minute = parseInt(time.split(":")[1]);
var today = new Date();
var givenDate = new Date();
givenDate.setHours(hour);
givenDate.setMinutes(minute);
if(givenDate < today) {
return true;
} else {
return false;
}
}
html:
<div ng-repeat="item in schedule">
<div>
Morning - {{item.morning}}
<span ng-if="isTimeUp(item.morning)">
Time's up!
</span>
</div>
<div>
Eveing - {{item.evening}}
<span ng-if="isTimeUp(item.evening)">
Time's up!
</span>
</div>
</div>
...and this is following your markup. You might want to implement a custom filter instead. But again, use moment.js.
Anyways, it seems to be working, though I haven't put much thought in it or tested it too much - see demo.

Resources