I' ve got a modal form "AddProductComponent" which is called inside "AddServiceRecordsComponent".
export class AddProductComponent implements OnInit {
id!: string;
isAddMode: boolean = false;
constructor(private fb: FormBuilder, private productService: ProductService,
private route: ActivatedRoute, private alertify: AlertifyService,
private router: Router, private activeModal: NgbActiveModal) {
}
productForm = this.fb.group({
name: ['', Validators.required]
});
ngOnInit(): void {
this.id = this.route.snapshot.params['id'];
this.isAddMode = !this.id;
if (!this.isAddMode) {
this.productService.getById(this.id).subscribe(product => {
this.productForm.patchValue(product);
})
}
}
save() {
const product: any = {};
Object.assign(product, this.productForm.value);
this.id = this.route.snapshot.params['id'];
this.isAddMode = !this.id;
if (!this.isAddMode) {
this.productService.updateProduct(this.id, product).subscribe(product => {
this.router.navigate(["products"]);
});
} else {
this.productService.saveProduct(product).subscribe(product => {
if (product != null) {
this.activeModal.close();
// I need to call a refresh products in the select box of AddRecordComponent
} else {
// etc....
}
});
}
}
}
This is my main form component which is calling modal form.
export class AddServiceRecordsComponent implements OnInit {
isAddMode: boolean = false;
id!: string;
serviceRecord!: ServiceRecord;
clients: Client[] = [];
products: Product[] = [];
brands: Brand[] = [];
deliveryTypes: Delivery[] = [];
productStatusses: ProductStatus[] = [];
serviceRecordForm: FormGroup;
serviceProcess!: ServiceProcess;
constructor(private fb: FormBuilder, private serviceRecordService: ServiceRecordService,
private clientService: ClientService, private productService: ProductService,
private deliveryService: DeliveryService, private brandService: BrandService,
private productStatusService: ProductStatusService, private alertify: AlertifyService,
private route: ActivatedRoute, private router: Router, private modalService: NgbModal) {
this.serviceRecordForm = this.fb.group({
client: [],
serviceRecordItem: this.fb.group({
productStatus: [''],
password: [''],
hasBackup: [''],
delivery: [''],
product: [''],
brand: [''],
serialNumber: [''],
defectDetail: [''],
}),
accessory: ['']
});
}
ngOnInit(): void {
this.id = this.route.snapshot.params['id'];
this.isAddMode = !this.id;
if (!this.isAddMode) {
this.serviceRecordService.getById(this.id).subscribe(serviceRecord => {
this.serviceRecordForm.patchValue(serviceRecord);
})
}
this.clientService.getClients().subscribe(clients => {
this.clients = clients;
})
this.productService.getProducts().subscribe(products => {
this.products = products;
products.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))
})
this.brandService.getBrands().subscribe(brands => {
this.brands = brands;
brands.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))
})
this.deliveryService.getDeliveries().subscribe(deliveries => {
this.deliveryTypes = deliveries;
})
this.productStatusService.getProductStatuss().subscribe(statusses => {
this.productStatusses = statusses;
})
}
save() {
const serviceRecord: any = {};
Object.assign(serviceRecord, this.serviceRecordForm.value);
this.id = this.route.snapshot.params['id'];
this.isAddMode = !this.id;
if (!this.isAddMode) {
this.serviceRecordService.getById(this.id).subscribe(serviceRecord2 => {
this.serviceProcess = serviceRecord2.serviceProcess;
serviceRecord.serviceProcess = this.serviceProcess;
this.serviceRecordService.updateServiceRecordService(this.id, serviceRecord).subscribe(() => {
this.router.navigate(["service-records"]);
});
})
} else {
this.serviceRecordService.saveServiceRecordService(serviceRecord).subscribe(() => {
parent.location.reload();
});
}
}
// Some helper methods
openModalAddProduct() {
const modalRef = this.modalService.open(AddProductComponent);
}
openModalAddBrand() {
const modalRef = this.modalService.open(AddBrandsComponent);
}
}
openModal methods calling another component and htlm has a code snippet like this to open this modal.
<div class="row">
<div class="col-md-10">
<select class="form-select" formControlName="product" id="product"
[compareWith]="compareObjectProduct">
<option [ngValue]="product" *ngFor="let product of products">
{{product.name}}</option>
</select>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-outline-danger" (click)="openModalAddProduct()">+</button>
</div>
</div>
Now what i want to do is close that modal after saving product (done) and refresh product dropdown options without refreshing whole page.
You need to refresh products variable, and then the list will populate itself. In short, you need to share data between components via productService.
You could use observables and store products in the service and share them via BehaviorSubject, and then subscribe from the components, but I think it would require a lot of refactoring, because I guess productService methods are mostly HTTP calls...
A quick-and-dirty way that doesn't require much refactoring could be to add an event emitter in the productService, subscribe to it from the AddServiceRecordsComponent, and then after you save the product in the service, emit from there back to the component to signal to fetch fresh products (moved to a separate method).
Try this:
productService:
AddServiceRecordsComponent:
Observable approach:
productService:
AddServiceRecordsComponent:
edit
or, as Zlatko pointed out, if you're using ng-bootstrap, you can utilize
result
promise: when the promise resolves, call separate method which will update products:AddServiceRecordsComponent: