Issue
I am having an issue with variable initialization in Typescript, but being used in html.
I am trying to initialize a Map<String, boolean> in typescript that keeps track of a users permissions that it takes from a JSON token, to other pages in my angular dashboard. I am trying to ensure that component keeps track of user permissions while they are logged in.
When trying to call the variable though to get the "boolean" value for a ngIf statement, it does not seem to be able to get the map and gives errors such as: "TS7052: Element implicitly has an 'any' type because type 'Map<String, boolean>' has no index signature. Did you mean to call 'get'?."
I have tried a few different methods and looked around for similar questions, but to not much avail. The component being shown is a "tab" in a "tab-group" that leads to different groups of href's.
My code so far is:
view.component.ts
@Component({
selector: 'app-view',
templateUrl: './view.component.html',
styleUrls: ['./view.component.css']
})
export class viewComponent implements OnInit {
hasLibraryAccess = new Map<String, boolean>();
constructor() { }
ngOnInit(): void {
this.hasLibraryAccess.set("lib1", true);
this.hasLibraryAccess.set("lib2", true);;
}
hasAccess() {
// pull user token and check DB for library access rights
// use for loop to update what libraries user has access to
}
get hasLibAccess() {
return this.hasLibraryAccess;
}
}
view.component.html:
<div class="d-flex">
<div class="container">
<div class="d-inline-block" style="margin-left: 8%; width: 80%">
<div class="btn-toolbar">
<div *ngIf="hasLibraryAccess[lib1]; then lib1True else lib1False"></div>
<ng-template #lib1True>
<div>
<a class="hexagon d-flex align-self-center" role="button" href="#">Library<br />One</a>
</div>
</ng-template>
<ng-template #lib1False>
<div>
<a class="hexagon-disabled d-flex align-self-center" role="button" href="#">Library<br />One</a>
</div>
</ng-template>
<div *ngIf="hasLibraryAccess[lib2]; then lib2True else lib2False"></div>
<ng-template #lib2True>
<div style="margin-left: 1px">
<a class="hexagon d-flex align-self-center" role="button" href="#">Library<br /> Two</a>
</div>
</ng-template>
<ng-template #lib2False>
<div style="margin-left: 1px">
<a class="hexagon-disabled d-flex align-self-center" role="button" href="#">Library<br />Two</a>
</div>
</ng-template>
</div>
</div>
view.component.css:
.hexagon {
width: 7.5vw;
height: 8.5vh;
color: black;
font-size: .9em;
justify-content: center;
text-align: center;
text-decoration: none;
background: #bfe8f7;
position: relative;
z-index: 1;
margin-bottom: 28.865px;
}
.hexagon::before {
content: "";
position: absolute;
top: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-bottom: 28.8675px solid #bfe8f7;
}
.hexagon::after {
content: "";
position: absolute;
bottom: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-top: 28.8675px solid #bfe8f7;
}
.hexagon:hover {
background: #7fd1ef;
z-index: 2;
transform: scale(1.15)
}
.hexagon:hover:before {
content: "";
position: absolute;
top: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-bottom: 29.8675px solid #7fd1ef;
}
.hexagon:hover:after {
content: "";
position: absolute;
bottom: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-top: 29.8675px solid #7fd1ef;
}
.hexagon-disabled {
width: 7.5vw;
height: 8.5vh;
color: black;
font-size: .9em;
justify-content: center;
text-align: center;
text-decoration: none;
background: #caced0;
position: relative;
z-index: 1;
margin-bottom: 28.865px;
}
.hexagon-disabled::before {
content: "";
position: absolute;
top: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-bottom: 28.8675px solid #caced0;
}
.hexagon-disabled::after {
content: "";
position: absolute;
bottom: -28.8675px;
left: 0;
width: 0;
height: 0;
border-left: 3.75vw solid transparent;
border-right: 3.75vw solid transparent;
border-top: 28.8675px solid #caced0;
}
The error appears on the html line *ngIf="hasLibraryAccess[lib1]; then lib1True else lib1False"
It sends: "Element implicitly has an 'any' type because type 'Map<String, boolean>' has no index signature. Did you mean to call 'get'?"
I then tried to use the getter with: *ngIf="hasLibAccess()[lib1]; then lib1True else lib1False",
but it sends: "TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'? Type 'Map<String, boolean>' has no call signatures."
I also tried: ngIf="hasLibAccess[lib1]; then lib1True else lib1False",
but still get sent: "TS7052: Element implicitly has an 'any' type because type 'Map<String, boolean>' has no index signature. Did you mean to call 'get'?"
I have looked around for other similar questions this morning, but many are using the map in a ngFor loop or trying to just bind the html to typescript. Thank you in advance for any advice or help provided.
Solution
you can not use Map directly in this way inside template. Use keyvalue pipe
<div *ngFor="let hasLibraryAccess of libraryAccess | keyvalue">
// use here your conditions like
<div *ngIf="libraryAccess.lib2; then lib2True else lib2False"></div>
</div>
Documentation https://angular.io/api/common/KeyValuePipe
Answered By - Passionate Coder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.