2

I'm trying to create a basic app in angular and I got the following issue. I have a component where I list all the recipes I have and every recipe has different data. I added a button to every recipe which opens up a modal with the additional information to that specific object, at least thats the plan. Right now I'm always showing the same data, no matter which button I click. Can I please have a few tips on how to continue and always show the correct data? For recipe2 -> recipe2 data.. right now I'm showing recipe 1 data for all the other recipes.

Here is the component:

<div class="col my-3">
<div class="card">
    <img [src]="recipe.imagePath" alt="{{ recipe.name }}" class="card-img-top">
    <div class="card-body">
        <h5 class="card-title">{{ recipe.name }}</h5>
        <p class="card-text">{{ recipe.preview }}</p>

        <div class="row">
            <div class="col text-center">
                <button type="button" class="btn btn-outline-primary" data-toggle="modal" data-target="#recipeModal">
                        Read More...
                </button>
            </div>
        </div>

        <div class="modal fade" id="recipeModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">{{ recipe.name }}</h4>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>

                    <div class="modal-body">
                        <p>{{ recipe.description }}</p>
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-outline-success">Add to List</button>
                        <button type="button" class="btn btn-outline-warning">Edit</button>
                        <button type="button" class="btn btn-outline-danger">Delete</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- <app-recipe-detail></app-recipe-detail> -->
    </div>
    <div class="card-footer">
            <small class="text-muted">Posted by: Random Name</small>
    </div>
</div>

And the typescript file:

import { Component, OnInit, Input } from '@angular/core';
import { Recipe } from '../../recipe.model';

@Component({
  selector: 'app-recipe-item',
  templateUrl: './recipe-item.component.html',
  styleUrls: ['./recipe-item.component.css']
})
export class RecipeItemComponent implements OnInit {
    @Input() recipe: Recipe;

  constructor() { }

  ngOnInit() {
  }

}

And here is how I display all recipes in a list component:

<div class="row">
  <app-recipe-item *ngFor="let recipeItem of recipes" [recipe]="recipeItem"></app-recipe-item>
</div>

Thanks in advance!

2
  • How many recipes do you have? Just two? First of all, it seems that you have only one button to show the recipe details. I would suggest you to create as many buttons as the number of recipes you have (Only if you want to dedicate a button to a single recipe). For that you need to bind the recipe id with the button. The #recipeModal that you have declared in the button, I cannot find it anywhere else. You should instead take the recipe id value from your file in your button and pass the id to your modal. Try it with two separate buttons with two separate id. Commented Aug 16, 2018 at 10:09
  • Yes, sorry I edited my post - I have all these items in a list component and I use ngFor to display all of them. Commented Aug 16, 2018 at 10:45

2 Answers 2

2

The problem is, all your modals will have the exact same static id of #recipeModal.

You can set dynamic IDs as well as the targets by utilizing the index of the ngFor like this:

*ngFor="let recipe of recipes; let i = index"

Then setting the id attribute per recipe dynamically like this:

<div class="modal fade" [attr.id]="'recipeModal' + i" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">

This part [attr.id]="'recipeModal' + i" will result in a unique id per recipe.

Finally for your button, you would bind to the data-target dynamically as well :

<button type="button" class="btn btn-outline-primary" data-toggle="modal" [attr.data-target]="'recipeModal' + i">

EDIT

Here is the way of passing down the input

  • Add a new input to the component : @Input() id: number;
  • Pass the index as input for each component: <app-recipe-item *ngFor="let recipeItem of recipes; let i = index" [id]="i" [recipe]="recipeItem"></app-recipe-item>
  • Edit the passed index to reference the ts: [attr.data-target]="'recipeModal' + {{id}}" and for the button as well : [attr.data-target]="'recipeModal' + {{id}}"
Sign up to request clarification or add additional context in comments.

2 Comments

It looks like this could be the solution. I'm getting recipeItemundefined now though because the ngFor and the recipe itself are in a different component. (as you can see above) What would be the best way to pass down the i variable to the item component?
In that case I'm not sure this is the best structure you can have. But you can easily pass down the index as an input to the 'app-recipe-item'. See my Edit :)
0

I see the thing like this:

In your list component where you need to display all yours recipes in your .ts you have your let recipes = Recipe[] then in your .html you'll have a kind of <div *ngFor="let recipe of recipes" class="card"> to loop trough your list and display the recipe and then when you click on your button you've on it the event (click)="detailsRecipe(recipe)"

This method detailsRecipe(recipe) could open into a modale the detailsRecipeComponent and maybe in this details component, calling a service to get more informations about the recipe and that's it. Of course it's a draft that I present you but this is the general idea. Now you need to investigate how to open a modal with component it's depend of documentation about which UI Components you choosed.

I hope it could help you.

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.