Search code examples
angularngforangular-ng-if

NgFor/NgIf multiply selection(favorites)


I have a weather app, where I want to mark multiply favorite cities by a "full heart" icon .

At the moment, when I click on different cities, the city before gets unmarked (kinda still buggy),

so basically I have only a single "full heart" icon showing, instead of afew.

Appreciate the help of modifying my app.

Adding and Removing favorites works as intended (displaying in 'Favorite' route), but I just cant figure

out how to combine it with the favorite icon.

https://stackblitz.com/edit/github-w3expd?file=src/app/weather-page/weather-page.component.html

Component.ts

setLikedCity(index:any){
    this.likedCity = index
  }
  

addToFav(name:any, local:any){
    let favCity = {
        name:name,
        local:local
    }
    console.log("local:", local, "name:", name)
    console.log("this.favoriteLocations:", this.favoriteLocations)
    
        if(this.favoriteLocations.length ==0){
            this.favoriteLocations.push(favCity)
            console.log("this.favoriteLocations:", this.favoriteLocations)
            console.log("ADDED")
        }
        
        else if(this.favoriteLocations.length > 0){
                let index;
                for(let i =0; i<this.favoriteLocations.length; i++){
                    if(this.favoriteLocations[i].name.Key ==favCity.name.Key){
                        index = i
                        // break;
                    }
                }
                
                if(index !=null){
                    this.favoriteLocations.splice(index, 1)
                    this.likedCity = ''
                    console.log("REMOVED")
                
                }else{
                    this.favoriteLocations.push(favCity)
                    console.log("ADDED")
                    }
                console.log("this.favoriteLocations:", this.favoriteLocations)
        }
        this.weatherService.favoriteLocations =  this.favoriteLocations
}

Component.html

<div class="container">
    <div class="small-container">
        <div class="row mt-5">
            <div class="card" style="width: 18rem;" *ngFor="let name of TelAvivSearch; let i = index;">
                <div class="card-body" style="text-align: center;">
                    <h5 class="card-title ">{{name.LocalizedName}}</h5>
                    <div *ngFor="let local of telAvivLocal ">
                        <p class="card-text ">{{local.WeatherText}}</p>
                        <p class="card-text ">{{local.Temperature.Metric.Value}}°</p>
                        <div *ngIf="i!==likedCity">
                            <i class="far fa-heart" (click)="addToFav(name, local);setLikedCity(i)"></i>
                        </div>
                        <div *ngIf="i===likedCity">
                            <i class="fas fa-heart" (click)="addToFav(name, local);"></i>
                        </div>
                    </div>
                </div>

            </div>

        </div>
    </div>
    <!-- favorites -->
    <div class="forecast-container mt-3 ">
        <h1 style="text-align: center; ">Forecast</h1>
        <div class="small-container ">
            <div class="row">
                <div *ngFor="let forecast of Forecast.DailyForecasts">
                    <div class="card " style="width: 13rem; ">
                        <div class="card-body" style="text-align: center;">
                            <h5 class=" card-title ">{{forecast.Date | date}} </h5>
                            <p class="card-text ">Day: {{forecast.Day.IconPhrase}}</p>
                            <p class="card-text ">Night: {{forecast.Night.IconPhrase}}</p>

                            <p class="card-text ">{{forecast.Temperature.Maximum.Value}}°<span>/ {{forecast.Temperature.Minimum.Value}}°</span></p>
                        </div>
                    </div>

                </div>
            </div>
        </div>
    </div>
</div>


Solution

  • You can add the following method in your commponent.ts and change the *ngIf condition on html side - it should work now.

      isLikedCity(key: number): boolean {
        const idx = this.favoriteLocations.findIndex(
          x => x.name['Key'] === key
        );
        return idx >= 0;
      }
      <div *ngIf="!isLikedCity(name.Key)">
           <i class="far fa-heart" (click)="addToFav(name, local);setLikedCity(i)"></i>
    </div>
    <div *ngIf="isLikedCity(name.Key)">
          <i class="fas fa-heart" (click)="addToFav(name, local);"></i>
    </div>