Home > Enterprise >  Passing value from component to service in angular
Passing value from component to service in angular

Time:08-25

I'm building an e-commerce website, when user click on any of the checkboxes I want to change products grid to what the user have clicked. I'm trying to pass the value of index from category-filter.component.ts to productgrid.service.ts but every time I got undefined result.

CategoryFilterComponent:

export class CategoryFilterComponent implements OnInit {

  selectedIndex: any = -1; // -1 because at screen load I do not want any checkboxes to be selected
  categoriesList: any= [];
  constructor(private categoryfilter: CategoryfilterService, private productList: ProductgridService) {
            this.categoryfilter.getCategories();
            this.categoriesList = this.categoryfilter.categoriesNames;
   }
  ngOnInit(): void {
  }

  changeSelection(event, index) {
    this.selectedIndex = event.target.checked ? index : undefined; // to only select one checkbox at a time
    index = this.selectedIndex ;
    this.productList.index = this.selectedIndex;
    console.log(this.productList.index) // works as intended
    // this.productList.saveIndex(this.selectedIndex);

  }
}

CategoryFilterHTML:

<div  *ngFor="let category of categoriesList[0]; let index = index">
    <input type="checkbox" [ngModel]="selectedIndex === index" (change)="changeSelection($event, index)">
    <label>{{ category | titlecase }}</label>
</div>

ProductgridService:

export class ProductgridService {

  allProducts: any[] = [];
  index: any;
  constructor(private http: HttpClient) {
   }
   ngOnInit(): void {

  }
 

  getAllProducts() {
     console.log(this.index)
    if(this.index == 0) {
      console.log(this.index)
      this.http.get('https://dummyjson.com/products/category/smartphones').subscribe({
        next: (data) => {
          this.allProducts.push(data);
          console.log(this.allProducts);
        }
      })
    } else if (this.index == 1){
      console.log(this.index)
      this.http.get('https://dummyjson.com/products/category/laptops').subscribe({
        next: (data) => {
          this.allProducts.push(data);
          console.log(this.allProducts)
        }
      })
    }
    else {
      console.log(this.index) // this only works
      this.http.get('https://dummyjson.com/products').subscribe({
        next: (data) => {
          this.allProducts.push(data);
        }
      })
    }
  }
}

productsGridComponent:

@Component({
  selector: 'app-products-grid',
  templateUrl: './products-grid.component.html',
  styleUrls: ['./products-grid.component.scss']
})
export class ProductsGridComponent implements OnInit {
  allProductList: any;
  singleCategorylist: any;
  index : number; 
  constructor(private productList: ProductgridService) {
    
    this.productList.getAllProducts();
    this.allProductList = this.productList.allProducts;
    // console.log(this.allProductList);
    // this.index = this.productList.index
    // console.log(this.index)
  }

  ngOnInit(): void {
    
  }

}

productsGridHTML:

<div  *ngFor="let product of allProductList[0]?.products; let i = index">
  <img  src="{{ product.thumbnail }}" alt="">
  <div >
    <p> -{{ product.discountPercentage }}% </p>
  </div>
  <p id="product-title">{{ product.title }}</p>
  <p id="product-description">{{ product.description }}.</p>
  <div >
    <p> <span id="price-dc"><span style="font-weight:bold;">{{ product.price }} </span> <span>USD</span> </span> <span
        style="font-weight:bold;">477.85 </span><span>USD</span></p>
  </div>
  <p >Brand: <span style="font-weight:bold;">{{ product.brand }}</span></p>
  <p >Category: <span style="font-weight:bold;">{{ product.category }}</span></p>
  <p >In stock: <span style="font-weight:bold;">{{ product.stock }}</span></p>
  <span ><img  [attr.src]="'assets/images/star-17.png'" alt=""> <span
      style="color:#F4B000;"> {{ product.rating }} </span> <span>({{ product.id }})</span> </span>
  <button >ADD TO CART</button>
</div>

I'm sorry if my code looks unorganized as I'm still beginner with no experience.

CodePudding user response:

In Angular you don't have to assign your injected services to your component class. So in the constructor in CategoryFilterComponent remove all assignments. In your code you can use the service directly. After doing so, it should work.

Also please remove the ngOnInit method from your service. It is only for components.

I hope this helps.

CodePudding user response:

Have you checked that you really got the expected value here?

    index = this.selectedIndex ;
    //is index defined at this point?
    this.productList.index = this.selectedIndex;

maybe changeSelection is fired without you realizing it try writing it like this:

    index = this.selectedIndex ;
    debugger
    this.productList.index = this.selectedIndex;

than the browser should pause when this line is hit and you can inspect the value.

Also i dont think its a good practice to expose a service variable and set it directly.

Btw you can give your variable multiple possible values:

    private index: number | undefinded; 

which forces you to implement checks for all possible values down the line.

  • Related