Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to refresh the page after delete in angular5

I was making a mean-stack shopping app(Angular 5). I have made a manage product component with a list of all the products and a delete button. Delete button works but the product is listed in table till now as it was deleted from database. So, I was wondering is there any possible way to re-render or refresh the component after deleting. I tried to navigate to same page but it won't work as angular does not allow that. Please can anyone help. I could not find any specific answer to my query on stackoverflow so I had to ask It.

My manage-product.component.ts is :-

import { Component, OnInit } from '@angular/core';
import { ProductManageService, ProductDetails } from '../product-manage.service';
import { AllService } from '../all.service';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Location } from '@angular/common';

@Component({
  selector: 'app-manage-product',
  templateUrl: './manage-product.component.html',
  styleUrls: ['./manage-product.component.css']
})
export class ManageProductComponent implements OnInit{

    prodData : ProductDetails = {
    prodName: '',
    prodPrice: '',
    prodImage: '',
    prodSize: ''
    }

    data: any=[];

  constructor(private add:ProductManageService,
    private router: Router,
    private http:HttpClient,
    private allService :AllService,
    private location : Location) { }

  addProduct(){
    this.add.addProduct(this.prodData).subscribe(()=>{
        console.log("SENT",this.prodData);
    },(err)=>{
        console.log("Error",err);
    })
  }

  delFunc(id){
    // console.log("Delete ",id);
    this.add.deleteProd(id);
    this.router.navigateByUrl("/reload");
  }

  ngOnInit() {

    this.allService.getAlldata().subscribe(data =>{
      console.log("data",data);
      this.data = data;
    });

    console.log(this.data);


}

}

My html file for manage component is:-

    <div class="container">

    <form (submit)="addProduct()">
      <div class="form-group">
        <label for="name">Product Name</label>
        <input name="prodName" type="text" class="form-control" id="name" placeholder="Tshirt" [(ngModel)]="prodData.prodName">
      </div>
      <div class="form-group">
        <label for="price">Price</label>
        <input name="prodPrice" type="text" class="form-control" id="price" placeholder="1.1" [(ngModel)]="prodData.prodPrice">
      </div>
      <div class="form-group">
        <label for="image">Price</label>
        <input name="prodImage" type="text" class="form-control" id="image" placeholder="Link to image" [(ngModel)]="prodData.prodImage">
      </div>
      <div class="form-group">
        <label for="size">Price</label>
        <input name="prodSize" type="text" class="form-control" id="size" placeholder="M" [(ngModel)]="prodData.prodSize">
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>

    <table class="table table-hover">
        <tr>
            <th>Product Name</th>
            <th>Product Price</th>
            <th>Product Size</th>
            <th> </th>
        </tr>
            <tr *ngFor="let prod of data">
                <td>{{ prod.prodName }}</td>
                <td>{{ prod.prodPrice }}</td>
                <td>{{ prod.prodSize }}</td>
                <td>
                    <input type="button" class="btn btn-danger" routerLink="/reload" (click) = "delFunc(prod._id)" class="del-btn"  value="Delete">
                </td>
            </tr>
    </table>

</div>

app.module.ts in case of you need:-

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';

import { AllService } from './all.service';
import {AuthGuardService} from './auth-guard.service';
import {AuthenticationService} from './authentication.service';
import { ProductManageService } from './product-manage.service';

import { AppComponent } from './app.component';
import { FrontComponent } from './front/front.component';
import { ContentComponent } from './content/content.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
import { ProfileComponent } from './profile/profile.component';
import { ManageProductComponent } from './manage-product/manage-product.component';

const routes = [
  {
    path: '',
    component: ContentComponent
  },
  {
    path: 'product',
    component: ProductDetailComponent
  },
  { 
    path: 'login',
     component: LoginComponent 
  },
  {
   path: 'register',
    component: RegisterComponent
  },
  {
   path: 'profile',
   component: ProfileComponent,
   canActivate: [AuthGuardService] 
  },
  {
    path: 'manage',
    component: ManageProductComponent,
  },
  { path: 'reload',
    redirectTo: 'manage',
    pathMatch: 'full'
  },
];

@NgModule({
  declarations: [
    AppComponent,
    FrontComponent,
    ContentComponent,
    ProductDetailComponent,
    RegisterComponent,
    LoginComponent,
    ProfileComponent,
    ManageProductComponent
  ],
  imports: [

    BrowserModule,
    FormsModule,
    HttpClientModule,
    HttpModule,
    RouterModule.forRoot(routes, {
      onSameUrlNavigation: 'reload'
    }),
  ],
  providers: [
    AllService,
    AuthenticationService, 
    AuthGuardService,
    ProductManageService
  ],
  bootstrap: [AppComponent],
  exports: [RouterModule]
})
export class AppModule { }
like image 977
Coder Avatar asked Mar 06 '18 14:03

Coder


1 Answers

Cause

Your table isn't being updated because the model ( data ) wasn't updated after the API call. There are a few ways to update the model, and I recommend either Options 3 or 2 in this answer.

Option 1

As some have already stated, the first way is to remove the element from the array in the view-model:

delFunc(id){
    this.add.deleteProd(id);
    this.data = this.data.filter(item => item.id != id);
}

The drawback to this approach is that even though the item has been removed in the frontend, how can you be sure that it has indeed been successfully removed from the database in the backend? Meaning, the item would be removed from your frontend HTML table even if this.add.deleteProd(id) isn't working properly and the object wasn't actually deleted in the backend. Hence you can't be sure if the frontend View accurately represents the reality of the backend.

Option 2

The second way is to "reload" the table by querying the backend again. This takes the "least work" as all you have to do is simply call the function to load the data again:

delFunc(id) {
    this.add.deleteProd(id)
    .subscribe(()=> {
        this.fetchData();
    });
}

ngOnInit() {
    this.fetchData();
}

fetchData() {
    this.allService.getAlldata().subscribe(data =>{
        this.data = data;
    });
}

Here, you gain "accuracy" of reality but sacrifice performance as you are making two REST calls each time you delete.

Option 3

The third way takes the "most work", but provides a compromise between accuracy of reality and performance. Basically you will need to re-write the backend such that after doing the database deletion, the backend REST/API method returns the new set of data that is now in the database.

Then, you can do something like this in your Angular component:

delFunc(id) {
    this.add.deleteProd(id)
    .subscribe(newData => {
        this.data = newData;
    });
}

This assumes that you have control over the backend code. You might need to do this.data = newData.json(); instead, depending on what the this.add.deleteProd(id) method returns.

Pick the option that best suits your situation. Let me know if this works for you.

like image 175
jamesngyz Avatar answered Oct 04 '22 03:10

jamesngyz