Angular ng-show won't eval correctly - html

So if my JSON array object returns this:
"Tools": [
{
"name": "Submit a Claim",
"position": 1,
"isOn": true,
"alert": null
},
{
"name": "My Recurring Claims",
"position": 2,
"isOn": true,
"alert": null
},
{
"name": "Online Enrollment",
"position": 3,
"isOn": false,
"alert": "Online enrollment is available for the upcoming plan year. Click here to enroll!"
},
And my ng-show html has this:
<div class="toolTile col-md-3" ng-show="Tools.name = 'Online Enrollment' && Tools.isOn==true ">
<a href="#/claimEnter">
<img class="toolIcon" src="ppt/assets/toolIcons/oe.svg">
<p>Online Enrollment</p>
</a>
</div>
<div class="toolTile col-md-3" ng-show="Tools.name = 'Submit a Claim' && Tools.isOn==true ">
<a ng-click="transId()" ng-href="{{ ppt.Globals.hasDebitCard ? '#/claimEnter' : '#/claimSub' }}" >
<img src="ppt/assets/toolIcons/submitclaim.svg" >
<p>Submit a Claim</p>
</a>
</div>
Why does it keep evaluationing to false? I have tried quite a few variations and the "Online Enrollments" should hide while the "Submit a Claim" should show.
Any ideas of what I may be doing wrong here?
Thanks much.

Hi Man You could not Post Code with Out Head and Tail. There were Some
Syntax Errors Which caused the trouble .
You Need to Provide a Plunker with Buggy Code at least for some help :-) .
When you got an array in object you need to iterate over it.
I have provided you a running Plunker :-
<div ng-repeat="tool in data.Tools">
<div ng-show="tool.name == 'Online Enrollment' && tool.isOn==false ">
Online Enrollment
</div>
<div ng-show="tool.name == 'Submit a Claim' && tool.isOn == true ">
Submit a Claim
</div>
</div>
Plunker :-
http://plnkr.co/edit/B01pKWLsUtA2JlTAPOd5?p=preview
Good Luck !! Let me Know Your Queries if any !!

Related

Refresh cdkDropListData after dialog closes and element is removed from array

I have the angular drag and drop list set up like this:
<div class="row col-12" *ngFor="let level of team_heirarchy; let i=index;">
<div class="col-3">
<p>{{level.name}}</p>
</div>
<div class="col-9">
<div cdkDropList id="{{level.key}}" [cdkDropListData]="level.value"
[cdkDropListConnectedTo]="heirarchy_levels" class="example-list" [cdkDropListDisabled]="level.disabled" (cdkDropListDropped)="drop($event)">
<div class="example-box" *ngFor="let item of level.value; let j=index;" cdkDrag>{{item}}
<button *ngIf="!level.disabled" mat-icon-button color="warn" (click)="deleteHeirarchyItem(i, j)"><mat-icon>cancel</mat-icon>
</button></div>
</div>
</div>
</div>
And the TS File:
team_heirarchy = [
{
"name": "Level 1(ROOT)",
"key": "level1",
"value": ["Administration"],
"disabled": true
},
{
"name": "Level 2",
"key": "level2",
"value": ["Lead HR", "Lead Manager"],
"disabled": false
}
]
deleteHeirarchyItem(i: number, j: number){
this.dialog.open(ConfirmDialogComponent, {
height: "auto",
width: "500px",
data:{
message: "Are you sure you want to delete this position.",
}
}).afterClosed().subscribe(result => {
if(result){
this.team_heirarchy[i].value.splice(j, 1)
}
})
}
The problem is, if I place this line
this.team_heirarchy[i].value.splice(j, 1)
outside the mat-dialog, the ui is updated instantly and the element is removed from the drop list.
But if I continue this way and wait till the user confirms and dialog closes with a positive result, the element is removed from the array but on the ui the element is still there until I try to drag an element.
Any help?

get result from array of objects retrieved from db and return to ng-template

I have a complex array of objects retrieved from db
Link to the Code
let arr = [
{
"userId": "-jgtgjS",
"firstName": "def",
"lastName": "yellow",
"email": "def#gm.com",
"otp": 0,
"otpExpiry": "",
"mobileNumber": 9852145987,
"createdOn": "2019-09-15T11:50:29Z",
"gender": "female",
"profilePic": "",
"friendList": {
"_id": "5d7e25852fffaa2858930878",
"userId": "-jgtgjS",
"friendCount": 0,
"userObject": "5d7e25852fffaa2858930877",
"allFriends": [
{
"friendId": "GsbItTr",
"requestSent": true,
"requestReceived": false,
"friendSince": 1568549711731,
"_id": "5d7e2b2f25207f161c718a64",
"friendObject": "5d7e285aa6132b179cfa917c"
},
{
"friendId": "ch4PXXn",
"requestSent": false,
"requestReceived": true,
"friendSince": "",
"_id": "5d7f16124c7b3f16ec308c1d",
"friendObject": "5d7dce8d2a719a1d188ed641"
}
],
"__v": 2
}
}]
Link to the Code
I am using *ngFor to display the friends in my template, but I also need to show whether he is friend or not, how can I pass the instance of *ngFor before display to .ts and then compute the boolean and then return back to the template so that the user displayed is friend or not.
Added a pic. Now the button shows add friend in each using ngFor. but depending on the status of each user the button would change to accept if a request is received or it will show friends if the request is already accepted and friendSince has some value
I am able to get the status like this.
ar[0].friendList.allFriends.forEach(element=>{
if (element.friendId=='ch4PXXn'){
sent=element.requestSent;
received=element.requestReceived;
}
});
if u refer to the image added.. u can see there are many users listed in the view using *ngfor. 'def yellow' is one of them. Now inside of users object there is another array of objects which stores all the friend request transactions happening. This view is being seen by userId 'ch4PXXn'. So I need to find the object inside allFriends with a friendId containing ch4PXXn and then based on other parameters like sent, received, since. I want to show a button which will give user ch4PXXn options to accept or show request sent.
Link to the Code
Try like this:
<div *ngFor="let friend of arr">
<h3>{{friend.firstName}} {{friend.lastName}}</h3>
<h4>{{friend.gender}} </h4>
<h5>{{friend.email}} </h5>
<h5>{{friend.mobileNumber}} </h5>
<table>
<tr>
<th>Friend Id </th>
<th>Is Friend </th>
</tr>
<tr *ngFor="let item of friend.friendList.allFriends">
<td>{{item.friendId}}</td>
<td>{{item.friendSince == '' ? 'Not Friend' : 'Friend'}}</td>
</tr>
</table>
</div>
Working Demo
You can use a nested *ngFor, where you iterate the allFriends array, and based on your conditions show different content:
<ng-container *ngFor="let a of friend.friendList.allFriends; let last = last">
<!-- First check that friend matches the current user -->
<div *ngIf="a.friendId === loggedInUser">
<!-- are you already friends? -->
<p *ngIf="a.friendSince">You are friends!</p>
<!-- You have received a request, but not yet accepted -->
<button *ngIf="a.requestReceived && !a.friendSince> Accept Friend request</button>
<!-- You have sent request, but user hasn't accepted -->
<button disabled *ngIf="a.requestSent && !a.friendSince">Friend Request Sent</button>
</div>
<!-- All above conditions are false, and it is last item in array -->
<button *ngIf="a.friendId !== loggedInUser && last">Add Friend</button>
</ng-container>
Here's a STACKBLIZ

iterate elements of a json using *ngFor only if they met a condition

I'm working on an angular 4 project calling a json through a service, everything works very well exept for a single thing, my json has the following simplified structure for understanding the problem:
{
"animals" [
{
"name" : "dog"
"subgroup": "vertebrate"
"class" : "mammal"
},
{
"name" : "pig"
"subgroup": "vertebrate"
"class" : "mammal"
},
{
"name" : "cat"
"subgroup": "vertebrate"
"class" : "mammal"
},
{
"name" : "snake"
"subgroup": "vertebrate"
"class" : "reptile"
},
{
"name" : "lizzard"
"subgroup": "vertebrate"
"class" : "reptile"
},
{
"name" : "crocodile"
"subgroup": "vertebrate"
"class" : "reptile"
},
]
}
and i want to iterate ONLY the objects with the "class" : "reptile"
i made this structure:
<div class="col-12 mb-3" *ngFor="let reptiles of animals">
<div *ngIf = "reptiles.class == reptile">
<div class="row">
<div class="col-12">
<h5 class="py-3 bg-dark text-white pl-3 mx-0 mb-3">{{reptiles.name}}</h5>
<p class="py-3 bg-dark text-white font-weight-light pl-3 m-0">{{reptiles.class}}</p>
</div>
</div>
</div>
</div>
but what happens is that it iterates three empty
<div class="col-12 mb-3" *ngFor="let reptiles of animals">
</div>
corresponding to the mammals, and i want that objects not to iterate at all, i want to iterate only the objects with the class "reptile".
how can i achieve that?
The easy fix is to use ng-container instead of a div to iterate:
<ng-container *ngFor="let reptiles of animals">
<div class="col-12 mb-3" *ngIf="reptiles.class == reptile">
<div>
<!-- ... -->
</div>
</div>
</ng-container>
Of course the template still iterates over these entries now, but it will not create any DOM node for it whatsoever (the magic of ng-container).
Possibly a better fix would be to instead filter in your component and only pass the data you want to display to the template:
// In your controller after receiving the animals data:
this.reptiles = this.animals.filter(a => a.class === "reptile");
// Template
<div *ngFor="let reptile of reptiles">...</div>
You can also write a filterBy pipe or take one from an existing library such as ngx-pipes. But beware that Angular discourages that as it easily becomes a performance pitfall.
I think that you can use this solution
Just filter by class property:
filterItemsOfType(type){
return this.items.filter(x => x.class == type);
}
Cheers,
#carlosrojas_o
you just need to filter your data in component like this:
this.filteredAnimals = this.animals.filter(animal => animal.class === "reptile"); // now use filteredAnimals in html template
Hope it will help

Angular.js view - display a description from a code-description json

I have list of schools each with a code for a school level instead of ES, MS, HM.
[
{
"nameOfInstitution": "Summer Elementary",
"schoolLevel": "01304"
},
{
"nameOfInstitution": "Grady Middle",
"schoolLevel": "02400"
}
]
I am planning to use another JSON to get the description of those codes from:
{
"schoolLevel": [
{"01302": "All levels"},
{"01304": "Elementary"},
{"02400": "Middle"},
{"02402": "High school"}
]
}
What is the proper way to display this in Angular in a view where it would look like?
<div class="item item-text-wrap">
<p ng-repeat="school in schools">{{school.nameOfInstitution}} - {{school.schoolLevel}}</p>
</div>
Should it 1). iterate through the main JSON and insert the description after "schoolLevel" or 2). should I use a look-up method to find out the description each time I display a school?
I would think the first option is the better choice, but can anyone share some snippets of code on how to best achieve that?
Thank you!
You can create a filter for lookup:-
DATA:-
$scope.schools=[
{
"nameOfInstitution": "Summer Elementary",
"schoolLevel": "01304"
},
{
"nameOfInstitution": "Grady Middle",
"schoolLevel": "02400"
}
];
$scope.schoollevel={
"schoolLevel": [
{"01302": "All levels"},
{"01304": "Elementary"},
{"02400": "Middle"},
{"02402": "High school"}
]
}
Filter:-
app.filter('level',function(){
return function(item,filter){
//console.log(item.schoolLevel);
var levelVal;
item.schoolLevel.forEach(function(level){
if(typeof level[filter]!='undefined'){
console.log(level[filter]);
levelVal=level[filter];
}
}
);
return levelVal;
}
});
HTML:-
<p ng-repeat="school in schools">{{school.nameOfInstitution}} -
{{schoollevel|level:school.schoolLevel }}</p>
Plunker
Below code should work
Markup
<div class="item item-text-wrap">
<p ng-repeat="school in schools">{{school.nameOfInstitution}} -
{{level.schoolLevel | filter: school.schoolLevel : true }}</p>
</div>
Code
$scope.level = {
"schoolLevel": [
{"01302": "All levels"},
{"01304": "Elementary"},
{"02400": "Middle"},
{"02402": "High school"}
]
}

Looping through json passed through to assemble partial as variable

I'm having trouble trying to loop through my JSON data with an a assemble site setup in the following structure:
-src
--content
---index.hbs
--data
---steps-data.json
--partial
---steps.hbs
The index.hbs in the content calls the partial passing through the object like so:
{{> steps steps-data}}
My steps-data.json file looks like so:
{
"steps":[{
"index": 1,
"title": "Find a product",
"description": "Go to a product page and click on the +PriceTrack short cut to add to your list."
},{
"index": 2,
"title": "Track its price",
"description": "Go to a product page and click on the +PriceTrack short cut to add to your list."
},{
"index": 3,
"title": "Purchase",
"description": "Go to a product page and click on the +PriceTrack short cut to add to your list."
}]
}
In my steps.hbs i've tried looping through the JSON data but its not.
<div class="g-col g-span4">
{{#each steps-data.steps}}
<div class="working-step">
<span class="number"></span><h3>{{title}}</h3>
</div>
<p>{{description}}</p>
{{/each}}
</div>
The problem I have is that its not looping through and not sure what I'm doing wrong.
Since you passed steps-data into the partial as it's context, you can access steps directly or with this.steps:
<div class="g-col g-span4">
{{#each this.steps}}
<div class="working-step">
<span class="number"></span><h3>{{title}}</h3>
</div>
<p>{{description}}</p>
{{/each}}
</div>