5

I have the HTML

<mat-card *ngFor="let shift of employer.shifts">

    <mat-card-content>

        <div *ngIf="getShiftLocation(shift);">

            <div>{{ getShiftLocation(shift)['title'] }}</div>
            <div>{{ getShiftLocation(shift)['phone'] }}</div>
            <div>{{ getShiftLocation(shift)['manager'] }}</div>                         

        </div>

    </mat-card-content>

</mat-card>

There's the function getShiftLocation(shift) which returns Location object's field value

The question is: is there any way to set the whole Location object in this HTML in order I could use it?

For example:

<pre>

   <div #location="getShiftLocation(shift)">
       <div>{{location.title}}</div>
   </div>
    
</pre>

Maybe the other way as well.

2
  • You can precompute that value from the component. Or you can use a separate component, with the shift location as input, to display the shift location. Commented Nov 25, 2018 at 12:01
  • Yes, I'm with you. I think I'll prepare shifts locations before my component's output. Commented Nov 25, 2018 at 12:26

4 Answers 4

2

One solution would be to save the result into a template variable, using syntactic sugar of the ngIf directive it will look like:

<mat-card *ngFor="let shift of employer.shifts">

  <mat-card-content>
    <div *ngIf="getShiftLocation(shift) as shiftLocation">
      <div>{{ shiftLocation.title }}</div>
      <div>{{ shiftLocation.phone }}</div>
      <div>{{ shiftLocation.manager }}</div>                         
    </div>
  </mat-card-content>
</mat-card>

But keep in mind that the method will eventually be called in each change-detection circle, so don't do complex calculations or CPU intensive tasks inside it.

Note: Also you should use the trackBy functionality of the ngForOf directive for better control when angular should reuse DOM elements.

Sign up to request clarification or add additional context in comments.

Comments

1

You can set the whole location inside the function to a variable and use the variable in the HTML.

declare a variable as

location : LocationType = {};

and inside the getShiftLocation

getShiftLocation(){
  this.location  = // assin the value
}

and use in the HTML as,

<div>{{location.title}}</div>

Remember, using function in template is a bad practice which would have some performance impact.

5 Comments

The downvote doesn't came from me, but using a function in a template isn't necessarily a bad practice, it depends on the complexity of that function. Also, in this case, your solution wouldn't help because he is using the function inside a ngForOf.
It's clearly shows that he is using function in ngFor, using function in ngFor is always a bad practice. Dude, im just suggesting to use a function to get the necessary data in the component level , i have not mentioned anywhere to use inside ngFor. think before downvoting
That's right you never mentioned it, but it could be somewhat misleading, but to get the idea to keep logic away from templates your answer is fine. Regarding the bad practise of using functions inside ngFor, it totally depends and you should know what you're doing. For example just to grab some nested values and perform a basic string transformation it would be fine, but it should be used together with trackBy.
A getter function isn't supposed to modify the state of the component. Modifying the state of the component at each iteration of the for loop, and relying on the order of evaluation of Angular is a terrible idea. Not to mention that your code doesn't match with what the OP is asking, and will cause the ngIf condition to always be false.
Unfortunately won't work in mys case as I have an array of shifts with locations in there
0

You could add the location to the shift class:

class Shift {
location: LocationType
}

So you could access it like:

<div *ngIf="shift.location">
    <div>{{ shift.location['title'] }}</div>
    <div>{{ shift.location['phone'] }}</div>
    <div>{{ shift.location['manager'] }}</div>                     

</div>

Comments

0

I dunno if anyone is looking for his but:

If you want to insert an integrated value, into a string, that is part of a function and is an argument, you need to use:

functionName( ( 'string' + variable + 'string' ))

you can also use concat like this:

functionName( ( 'string'.concat( variable) ))

they key are () so you surround your full string code with () and it counts as a single argument.

<div *ngFor="let valueAsInMap of global.topHeroes">
    <div class="mb-4 topHero p-2">
        <a routerLink="/single-hero/{{valueAsInMap.id}}" (click)="global.logMessage(('moved to hero with id:'+valueAsInMap.id+'some other string'))">{{valueAsInMap.name}}</a>
    </div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.