angular: how to iterate over unlike objects and render different templates - angularjs

Say I have:
$scope.array = [{type: 'event'}, {type: 'alert'}];
How can I iterate over that and render a different item out of $templateCache for each, based on type. We can assume 'event.html' and 'alert.html' exist.

What other than Keegan's answer you can do is :
<div ng-repeat='a in array'>
<div ng-include="a.type + '.html'"></div>
</div>
This way you get event.html or error.html loaded as per the value

I think what you're looking for is the following.
<div ng-repeat='a in array'>
<div ng-if="a.type =='event'">
// EVENT.html TEMPLATE
</div>
<div ng-if="a.type == 'alert'">
// ALERT.html TEMPLATE
</div>
</div>

Related

Using ng-if inside ng-repeat doesn't work

I have an array called polls with many objects poll. Each poll has a property moduleState which is initally set to the string "notVoted". The moduleState for an individual poll may later be set to the string "voted". Here is the template for one of my partials:
<div ng-init="loadPage()">
<div ng-repeat="poll in polls">
<div ng-if="poll.moduleState === 'notVoted'">
//Template 1
</div>
<div ng-if="poll.moduleState === 'voted'">
//Template 2
</div>
</div>
</div>
The problem is, both templates are used for each poll in polls. So if there were 3 poll objects in the array polls, the partial would put out:
Template 1
Template 2
Template 1
Template 2
Template 1
Template 2
I suspect this is because of a weird interaction between ng-if and ng-repeat. How can I get it so only one template per poll shows?
Edit: As requested, here is a console.log of a poll object. As you can see, moduleState is in fact set to "notVoted"
Even though this is not the answer but this post represent how should we proceed for troubleshooting this sort of issues.
<div ng-init="loadPage()">
<div ng-repeat="poll in polls">
<span>poll.moduleState: {{poll.moduleState}}</span>
<div ng-if="poll.moduleState === 'notVoted'">
//Template 1
</div>
<div ng-if="poll.moduleState === 'voted'">
//Template 2
</div>
</div>
</div>
note I have introduced test span to check how much time loop iterates and what is the value of that poll object property.
More ever you can also use some chrome extensions that extracts property value from the current runtime ng binding and shows in the developer tool. You can find that tool here. Explore how you can utilize the tool to find out what values are being bind in the dom element and get your issue resolved. :)
Hope this helps you.
Your code is fine ng-if works in ng-repeat:
HTML:
<div>
<div ng-repeat="poll in polls">
<div ng-if="poll.moduleState === 'notVoted'">
<!-- Template 1 -->
Not Voted: {{poll.name}}
</div>
<div ng-if="poll.moduleState === 'voted'">
<!-- Template 2 -->
Voted: {{poll.name}}
</div>
</div>
</div>
</div>
Angular:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.polls =
[
{
"name": "module1",
"moduleState": "notVoted"
},
{
"name": "module2",
"moduleState": "voted"
}
];
});
Here is the fiddle showing ng-if working with ng-repeat: https://jsfiddle.net/AKMorris/nkqkunfr/
I was facing the same problem. honestly still don't know the reason why, but I work it in another way as making it in reverse, for the example above it should be something like :
<div ng-if="poll.moduleState === 'notVoted'">
<div ng-repeat="poll in polls">
//Template 1
</div>
</div>
<div ng-if="poll.moduleState === 'voted'">
<div ng-repeat="poll in polls">
//Template 2
</div>
</div>

How to create div and assign object to dataset dynamically using Angularjs

I have below div (class name 'sp') which I would like to dynamically create based on the sk from a dataset object.
div code
<div style="" class="swindow">
<div class="sp" style="">
<div class="svis" style="">
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
</div>
</div>
While searching for similar examples, I came across ng-repeat in Angular js and I thought it might suit for this kind of objective.
But am very new to Angular js and not sure how to assign the data to my dyndata variable dynamically and create new div (class=sp) for each of the given id.
Here is the lookup object
[
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
When I input the id's as a set [12,26,57] - Three divs (each for #sp) should get created one for each of ids. In those, each div should have the dyndata assigned with the respective 'st' from above javascript object.
I could create div's in jquery using .append function to the container (#swindow) each time when I need. But am not sure how to assign sk as input to dyndata dataset for each div that gets created.
Could you please share how this can be achieved using Angular js ?
Here is the angular js code I used -
<script>
var app = angular.module('ExampleApp', ['ui.plot']);
app.controller('PlotCtrl', function ($scope) {
$scope.dyndata={};
});
</script>
I'm not exactly sure what you're trying to do but I think it should look something like this. Here is a plnkr..
Controller:
app.controller('PlotCtrl', function($scope) {
$scope.items = [
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
});
HTML:
<body ng-controller="PlotCtrl">
<div style="" class="swindow">
<div class="sp" style="" ng-repeat="item in items">
<div class="svis" style="">
<strong>{{item.id}}:</strong>
<div>-{{item.st[0].label}}</div>
<div>-{{item.st[1].label}}</div>
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
<br>
</div>
</div>
</div>
</body>

Two Way data Binding in Angular js

I am using nodejs + Angular and html as a froentend
Here is my HTML Code
<div id="container" ng-app='two_way' ng-controller='two_way_control'>
<div class="row" ng-repeat="data in profile_pictures">
<div class=".col-sm-6 .col-md-5 .col-lg-6" style="background-color:#eee;height:150px;width:500px;margin-left:240px;margin-top:20px;">
<h4 style="padding:10px;">User Say's</h4><hr>
<img src="{{data.profile_picture}}" class="img-circle" style="width:100px;height:100px;margin-left:-140px;margin-top:-130px;">
</div>
</div>
</div>
and my angular code is here
app.controller('two_way_control',function($scope,$http,$interval){
load_pictures();
$interval(function(){
load_pictures();
},300);
function load_pictures(){
$http.get('http://localhost:3000/load').success(function(data){
$scope.profile_pictures=data;
});
};
});
and my server code is
app.get('/load',function(req,res){
connection.query("SELECT * from user_info",function(err,rows){
if(err)
{
console.log("Problem with MySQL"+err);
}
else
{
res.end(JSON.stringify(rows));
}
});
});
Which is working fine..
When i entered a new record in **user_info*. it will display new record to me.
Is this right way to do two way data binding or i am missing something
Please help.
Thanks
It looks as if you're doing one way binding because your angular code is never modifying the profiles pictures in the table (meaning you ain't got no form fields, your page is read only). But AFAIK you're doing everything right, as soon as you add editing capabilities to your angular page you would be doing two way binding all the way
YES! Angular '2-way bind' is between scope.variable and VIEW (ng-model in input elements).
In this case, the SRC property of IMG element need to be setd with ng-src!
Because IMG is a html element that load before angular principal scripts.
<div id="container" ng-app='two_way' ng-controller='two_way_control'>
<div class="row" ng-repeat="data in profile_pictures">
<div class=".col-sm-6 .col-md-5 .col-lg-6" style="background-color:#eee;height:150px;width:500px;margin-left:240px;margin-top:20px;">
<h4 style="padding:10px;">User Say's</h4><hr>
<img ng-src="{{data.profile_picture}}" class="img-circle" style="width:100px;height:100px;margin-left:-140px;margin-top:-130px;">
</div>
</div>
</div>

AngularJS: Best practice displaying static text based on a state/variable

I have small text portions like
<div>
<h4>Why Register?</h4>
<p>As candidate...</p>
</div>
opposed to
<div>
<h4>Why Register?</h4>
<p>As company...</p>
</div>
Based on a variable in my controller I insert the correct partial with:
<div ng-switch on="role">
<div ng-switch-when="candidate">
<div ng-include="'candidate.html'"></div>
</div>
<div ng-switch-when="company">
<div ng-include="'company.html'"></div>
</div>
<div ng-switch-default>
<div ng-include="'candidate.html'"></div>
</div>
</div>
This does the job but it looks awful. Is there any way I could do it better?
You could always hold your string vars in javascript or external json file and use markup which is tied to a model like this:
<div ng-controller="something">
<h4>Why Register?</h4>
<p>{{who}}</p>
</div>
and then inside your "something" controller provide code:
if(role == "company")
$scope.who = "As company...";
else
$Scope.who = "As candidate...";
If you have many places in code that use such feature, you could consider holding variables in external json and then reading them in javascript/controller.
You can use:
<div ng-include="(role || 'candidate') + '.html'"></div>
If the parts are not that big you can put them all up there and use ng-show to filter which gets actually shown. This takes up the least markup.
<h4>Why register?</h4>
<p ng-show="isCompany">Company targeted content...</p>
<p ng-show="isCandidate">Candidate targeted content...</p>

change angular ui-view inside ng-repeat

I am using multiple named ui-views in a single controller. Everything is working as spected when name the ui-view in the html file with this code:
<div class="box">
<div ui-view="selector"></div>
<div ui-view="widget1"></div>
<div ui-view="widget2"></div>
<div ui-view="widget3"></div>
<div ui-view="widget4"></div>
</div>
But when I want to load dynamically some of those views with a ng-repeat it does not update the information.
<div class="widgets">
<div class="widget-container" ng-repeat="widget in widgets">
<div ui-view="{{widget}}"></div>
</div>
</div>
How could I load ui-views from my ng-repeat?
This hadn't been answered so i decided to go ahead and show how to do it. Unfortunately for some reason the attempt in the question didn't work but what you can do is link to a function between curly brackets and return the string of the view you want. For instance the controller would look like this:
$scope.groups = ['main','cases', 'models'];
$scope.pickView = function(index){
return $scope.groups[index];
};

Resources