Home > Back-end >  Pulling Typescript Hashmaps to HTML variable
Pulling Typescript Hashmaps to HTML variable

Time:08-24

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 >
  <div >

    <div  style="margin-left: 8%; width: 80%">
      <div >
        <div *ngIf="hasLibraryAccess[lib1]; then lib1True else lib1False"></div>
        <ng-template #lib1True>
          <div>
            <a  role="button" href="#">Library<br />One</a>
          </div>
        </ng-template>
        <ng-template #lib1False>
          <div>
            <a  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  role="button" href="#">Library<br /> Two</a>
          </div>
        </ng-template>
        <ng-template #lib2False>
          <div style="margin-left: 1px">
            <a  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.

CodePudding user response:

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

  • Related