Hi y'all So I have a component(let's call this recipe component) that has a ref to another component(Let's call this grocery component).
My recipe component has a reference to grocery component. A method in my recipe component uses the grocery component ref to call a method within the grocery component.
The recipe component method is called addToGroceryList(recipeName,ingredients) this method uses the grocery component reference to call groceryComponenent.addToGroceryList(recipeName,ingredients)
And when I do this my dom doesn't get updated and for the life of me I can't figure out why. How ever I made a temporary button in my grocery Component html to call groceryComponent.addToGroceryList("test1",["test"]) and when I use this mock button the dom updates just fine. So I know the issue is because I'm invoking methods through a reference.
Anyways here's my code. groceryList is my reference to my other component
RecipeComponent:
import {Component} from '@angular/core';
import {GetRecipesService} from './getrecipes.service'
import { TagInputModule } from 'ngx-chips';
import {GrocerySidebarComponent} from "./grocery-sidebar/grocery-sidebar.component";
TagInputModule.withDefaults({
tagInput: {
placeholder: 'Add a ag',
// add here other default values for tag-input
},
dropdown: {
displayBy: 'my-display-value',
// add here other default values for tag-input-dropdown
}
});
@Component({
selector: 'recipes', //<recipes>
styleUrls: ['./recipes.component.css'],
template: `
<script src="angular.min.js"></script>
<script src="ng-tags-input.min.js"></script>
<div class="recipeContainer container-fluid">
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="recipeNameInput1">Recipe Name</label>
<input [(ngModel)] ="formRecipeName" name="formRecipeName" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<tag-input [(ngModel)]="formIngredients" id="ingredientTags" [modelAsStrings]="true" name="formIngredients" [secondaryPlaceholder]="'Enter Ingredient'"> </tag-input>
</div>
<button type="submit" class="btn btn-primary" (click)="addRecipe()" data-dismiss="modal">Submit</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Are you Sure Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Are you sure?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<button type="submit" class="btn btn-primary" (click)="deleteRecipeInBuffer()" data-dismiss="modal">Delete</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="album py-5 bg-light">
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<a class="navbar-brand" href="#"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" data-toggle="modal" data-target="#exampleModal">Add Recipe</button>
</li>
<li class="nav-item">
</li>
</ul>
<form class="form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<div class="row">
<div class="col-md-4" *ngFor = "let recipe of recipeList;trackBy:trackByIdCode">
<div class="card mb-4 box-shadow">
<sup>
<button type="button" data-toggle="modal" data-target="#deleteModal" class="close" aria-label="Close" (click)="prepareToDelete(recipe._id)">
<span aria-hidden="true">×</span>
</button>
</sup>
<h5 class="card-title">{{recipe.recipeName}} </h5>
<div class="card-body" >
<p class="card-text">{{recipe.recipeIngredients}}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary" (click)="addToGroceryList(recipe.recipeName,recipe.recipeIngredients)">Add To Grocery List</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
TODO: Edit Recipe. Ingreidents with quantity. Ingredients with style (Chopped. Diced. Sautee..etc). Search or Filter (by name or ingredient).
TODO: Add to grocery List. Undo Button
`,
})
export class RecipesComponent{
constructor(getRecipesService: GetRecipesService,groceryList:GrocerySidebarComponent){
getRecipesService.getRecipes().subscribe(promise=>{
this.recipeList = promise;
this.recipeList = this.recipeList.data;
console.log(this.recipeList);
});
this.recipeService=getRecipesService;
this.groceryList = groceryList;
}
addToGroceryList(recipe,ingredients){
this.groceryList.addToGroceryList(recipe,ingredients);
}
//when user presses x on card, the id is stored here. Then are you sure window appears
//if yes on are you sure then delete whats in buffer
//else clear what's in buffer
prepareToDelete(recipeId){
this.deleteBuffer = recipeId;
}
//if yes after are you sure, delete whats in buffer
deleteRecipeInBuffer(){
this.deleteRecipe(this.deleteBuffer);
}
addRecipe(){
this.recipeService.addRecipe(this.formRecipeName,this.formIngredients).subscribe(promise=>{
console.log("promise"+promise);
this.refreshRecipeList();
this.formIngredients = undefined;
this.formRecipeName = undefined;
});
}
deleteRecipe(recipeId){
this.recipeService.deleteRecipe(recipeId).subscribe(promise=>{
console.log(promise);
this.refreshRecipeList();
})
}
refreshRecipeList(){
this.recipeService.getRecipes().subscribe(promise=>{
console.log("refreshed");
this.recipeList = promise.data;
});
}
public trackByIdCode(index: number, recipe: any): string {
return recipe._id;
}
deleteBuffer;//buffer is used to store recipeId => are you sure window comes up. if yes then delete whats in deleteBuffer
formRecipeName;//form value in modal
formIngredients; //form value in modal
recipeService;//http access service
recipeList;//list of all recipes recieved from recipeService
groceryList;
}
//
Grocery Component:
import { Component, OnInit, NgModule,ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core';
import {GetRecipesService} from '../getrecipes.service';
import { MatIconRegistry } from "@angular/material/icon";
import { DomSanitizer } from "@angular/platform-browser";
@Component({
selector: 'app-grocery-sidebar',
templateUrl: './grocery-sidebar.component.html',
styleUrls: ['./grocery-sidebar.component.css'],
changeDetection: ChangeDetectionStrategy.Default,
})
export class GrocerySidebarComponent {
constructor(getRecipesService: GetRecipesService,private matIconRegistry: MatIconRegistry,private domSanitizer: DomSanitizer,private cdr:ChangeDetectorRef) {
getRecipesService.getGroceryList().subscribe(promise=>{
this.groceryList = promise.data;
});
this.recipeService=getRecipesService;
this.matIconRegistry.addSvgIcon("shopping_cart",this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/shopping-cart-solid.svg"));
this.CDR = cdr;
}
addToGroceryList(recipeName,recipeIngredients){
console.log("Entered addToGroceryList");
this.recipeService.addToGroceryList(recipeName,recipeIngredients).subscribe(promise=>{
console.log("promise returned from addToGroceryList()")
this.refreshGroceryList();
});
}
refreshGroceryList(){
this.recipeService.getGroceryList().subscribe(promise=>{
this.groceryList = promise.data;
console.log("refreshed");
})
}
deleteGroceryRecipeById(groceryId){
console.log("Delete requested: "+groceryId);
this.recipeService.deleteGroceryRecipeById(groceryId).subscribe(promise=>{
this.refreshGroceryList();
});
}
public trackByCode(index: number, recipe: any): string {
console.log("tracking");
return recipe._id;
}
CDR;
recipeService;
groceryList: object[];
showFiller=false;
}
Grocery HTML:
<div class="accordion" id="accordionExample">
<div class="card" *ngFor="let grocery of groceryList;trackBy:trackByCode; index as index;">
<div class="card-header" [id]="'grocery1'+index">
<h5 class="mb-0">
<button class="btn btn-link" type="button" attr.data-toggle="collapse" [attr.data-target]="'#grocery2'+index" attr.aria-expanded="false" [attr.aria-controls]="'grocery2'+index">
{{grocery.recipeName}}
</button>
<sup>
<button type="button" class="close" aria-label="Close" (click)="deleteGroceryRecipeById(grocery._id)">
<span aria-hidden="true">×</span>
</button>
</sup>
</h5>
</div>
<div [id]="'grocery2' + index" class="collapse" [attr.aria-labelledby]="'grocery1'+index" attr.data-parent="#accordionExample">
<div class="card-body">
<ul class="list-group" id="filterList">
<li class="list-group-item">
<a href="#" class="list-down-btn" attr.data-toggle="#subgroup"><span class="glyphicon glyphicon-chevron-down"></span></a>
<ul id="subgroup" class="list-group">
<li class="list-group-item" *ngFor="let ingredient of grocery.ingredients">{{ingredient}}</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<sup>
<button type="button" class="close" aria-label="Close" (click)="addToGroceryList('test',['test']) ">
<span aria-hidden="true">×</span>
</button>
</sup>
<mat-icon svgIcon="shopping_cart"></mat-icon>
Again just to re-iterate the dom updates fine when I call addToGroceryList() from within my grocery component. But when I use a ref to call addToGroceryList from another component the dom doesn't update. Does anyone have any ideas what's going on here?