Home > Mobile >  Angular, the newly added item can only be deleted after refresh
Angular, the newly added item can only be deleted after refresh

Time:12-06

I'm working on an Angular 12 project, and I'm storing the data using JSON-server. The CRUD operations are working fine.

But when I add a new item, using the form, the delete and update buttons won't work, unless I refresh the page.

This the error I get in the console , after I click on the delete button, (without refreshing).

product.service.ts

  url = environment.url   'products/';
  constructor(private http: HttpClient) {}

  getListProduct() {
    return this.http.get<Product[]>(this.url);
  }

  addProduct(product: Product) {
    return this.http.post(this.url, product);
  }

  deleteProduct(id: string) {
    return this.http.delete(this.url   id);
  }
  updateProduct(product: Product) {
    return this.http.put(this.url   product.id, product);
  }
}

main-product.component.ts

export class MainProductComponent implements OnInit {
 inputProduct: Product = new Product();
 isForm: Boolean = false;
 buttonString: String = 'Add New Product';
 listProduct: Product[] = [];

 constructor(private productService: ProductService) {}

 ngOnInit(): void {
   this.productService
     .getListProduct()
     .subscribe((data: Product[]) => (this.listProduct = data));
 }
 changePage() {
   this.isForm = !this.isForm;
   if (this.isForm) {
     this.buttonString = 'Go Back To List';
   } else {
     this.inputProduct = new Product();
     this.buttonString = 'Add New Product';
   }
 }
 deleteProduct(p: Product) {
   let i = this.listProduct.indexOf(p);
   this.productService
     .deleteProduct(p.id)
     .subscribe(() => this.listProduct.splice(i, 1));
 }
 saveProduct(product: Product) {
   let i = this.listProduct.indexOf(product);
   if (i != -1) {
     //update a product
     this.productService
       .updateProduct(product)
       .subscribe(() => (this.listProduct[i] = product));
   } else {
     //add a new product
     this.productService.addProduct(product).subscribe(
       () => this.listProduct.push(product),
       () => console.log('error')
     );
   }
   this.isForm = false;
   this.buttonString = 'Add New Product';
   this.inputProduct = new Product();
 }

 updateProduct(p: Product) {
   this.isForm = true;
   this.inputProduct = p;
 }

form-product.component.ts

export class FormProductComponent implements OnInit {
  selectedFile = null;
  private product!: Product;
  productForm!: FormGroup;
  @Input() updateProduct!: Product;
  @Output() addEvent = new EventEmitter<Product>();
  constructor(private builder: FormBuilder) {}

  ngOnInit(): void {
    if (this.updateProduct === null) {
      this.product = new Product();
    } else {
      this.product = this.updateProduct;
    }

    this.productForm = this.builder.group({
      title: [
        this.product.libelle,
        [Validators.required, Validators.minLength(3)],
      ],
      price: [
        this.product.prixUnitaire,
        [Validators.required, Validators.min(10)],
      ],
      photo: [this.product.photo, Validators.required],
      category: [this.product.categorie, Validators.required],
    });
  }
  upload(event: any) {
    this.selectedFile = event.target.files[0].name;
    console.log(this.selectedFile);
  }
  addProduct() {
    this.product.libelle = this.productForm.value.title;
    this.product.prixUnitaire = this.productForm.value.price;
    this.product.photo = String(this.selectedFile);
    this.product.categorie = this.productForm.value.category;

    this.addEvent.emit(this.product);
  }
}

CodePudding user response:

It's a little hard to say for sure, but it looks like you aren't saving off the response from the create in your array on the front end.

Most likely the code should be as follows

// add a new product
     this.productService.addProduct(product).subscribe(
       newProduct => this.listProduct.push(newProduct),
       () => console.log('error')
     );

I wrote the above quickly on my phone, here is a more detailed answer.

I've never used json-server before, so that is an unknown to me. From their docs, in their examples, they are creating the id on the object before sending it to the json server. I can't see your product class so I don't know if you are generating an id for your objects or not...my guess is not.

The most common work flow for something like this is that the front-end will create an object without an id, send it to the backend, which will persist it in a data store of some sort. That process also generates the id for that object and returns it as a part of the object from the create call. The front-end is then able to perform further actions on that object via the id(get, put, delete, etc).

In your code, you weren't taking the object returned by the backend and pushing that into your array, but rather you were pushing the object that you were sending to the backend in your array. Again, in a typical scenario that wouldn't have an id.

If json-server requires you to create and assign the id, then you'll need to update your product class to assign an id when it gets newed up.

The logic you have to get the product from the array is working because the error you are getting isn't that it can't find 'id of undefined' rather, the code is finding the product, but the id property on that product object is undefined.

Again, normally that id comes from the back end and if that was happening here, then you wouldn't be getting it because you aren't adding the object that is coming from the back end to your array. If json-server requires you to pass it the id, then you will need to update your front end code to generate the id and then everything should work for you.

CodePudding user response:

peinearydevelopment is right. also you can refetch the list after add or delete. (in case you want to run some calculations and queries or set some server-side ordering to the list)

Something like:

constructor(private productService: ProductService) {}

 ngOnInit(): void {
   this.fetchList();                                                  // This Line
 }

 fetchList() {                                                        // This Function
   this.productService
     .getListProduct()
     .subscribe((data: Product[]) => (this.listProduct = data));
 }
 deleteProduct(p: Product) {
   let i = this.listProduct.indexOf(p);
   this.productService
     .deleteProduct(p.id)
     .subscribe(() => {
       this.fetchList();                                              // This Line
     });
 }
 saveProduct(product: Product) {
   let i = this.listProduct.indexOf(product);
   if (i != -1) {
     //update a product
     this.productService
       .updateProduct(product)
       .subscribe(() => (this.listProduct[i] = product));
   } else {
     //add a new product
     this.productService.addProduct(product).subscribe(() => {
       this.fetchList();                                              // This Line
     }, () => console.log('error'));
   }
   this.isForm = false;
   this.buttonString = 'Add New Product';
   this.inputProduct = new Product();
 }
  • Related