router.put("/:id", authenticateUser, isSuperAdmin, async (req, res) => { const existingCategory = await Category.findById(req.params.id); const category = await Category.findByIdAndUpdate( req.params.id, { name: req.body.name, image: req.body.icon || existingCategory.image, }, { new: true } ); if (!category) return res .status(400) .json(createResponse("Error", 400, errorMessages.updated("category"))); res.status(200).json( createResponse("success", 200, successMessages.updated("category"), { categoryUpdated: category, }) ); }); <p>category-add works!</p> <form [formGroup]="categoryForm" (ngSubmit)="onSubmit()" enctype="multipart/form-data"> <mat-form-field appearance="fill"> <mat-label>Category Name</mat-label> <input matInput id="name" formControlName="name" /> <mat-error *ngIf="categoryForm.get('name')?.invalid && categoryForm.get('name')?.touched"> <small *ngIf="categoryForm.get('name')?.errors?.['required']">Name is required</small> <small *ngIf="categoryForm.get('name')?.errors?.['minlength']">Name must be at least 3 characters long</small> </mat-error> </mat-form-field> <mat-card> <mat-card-content> <h2 class="mat-h2">Category Icon</h2> <div class="media_select"> <button mat-raised-button color="primary" type="button" (click)="triggerFileInput()">Choose File</button> <input hidden (change)="onFileSelected($event)" #fileInput type="file" /> </div> <div class="mt-3" *ngIf="imageUrl"> <h2 class="mat-h2">Uploaded Image</h2> <div class="image-preview-container"> <img [src]="imageUrl" alt="Preview" width="150"> <button mat-icon-button class="remove-btn" color="warn" (click)="removeImage()"> <mat-icon>cancel</mat-icon> </button> </div> </div> </mat-card-content> </mat-card> <div class="submit-btn-container"> <button mat-raised-button color="accent" [disabled]="categoryForm.invalid">Submit</button> </div> </form> import { CommonModule } from '@angular/common'; import { Component, OnInit, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { HttpService } from 'src/app/services/http.service'; import { Router, ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-category-add', templateUrl: './category-add.component.html', styleUrls: ['./category-add.component.scss'], standalone: true, imports: [ CommonModule, ReactiveFormsModule, MatButtonModule, MatCardModule, MatFormFieldModule, MatInputModule, MatIconModule ] }) export class CategoryAddComponent implements OnInit { categoryForm!: FormGroup; selectedFile: File | null = null; imageUrl: string | ArrayBuffer | null = null; categoryId: string | null = null; @ViewChild('fileInput') fileInputRef!: ElementRef<HTMLInputElement>; constructor( private fb: FormBuilder, private router: Router, private route: ActivatedRoute, private cdr: ChangeDetectorRef, private httpService: HttpService ) {} ngOnInit(): void { this.initializeForm(); this.route.paramMap.subscribe(params => { this.categoryId = params.get('id'); if (this.categoryId) { this.getCategoryDetails(this.categoryId); } }); } private initializeForm(): void { this.categoryForm = this.fb.group({ name: ['', [Validators.required, Validators.minLength(3)]], icon: [''] }); } onFileSelected(event: Event): void { const input = event.target as HTMLInputElement; if (input.files && input.files[0]) { this.selectedFile = input.files[0]; const reader = new FileReader(); reader.onload = (e) => { this.imageUrl = e.target?.result; this.cdr.detectChanges(); }; reader.readAsDataURL(this.selectedFile); this.categoryForm.patchValue({ icon: this.selectedFile }); } else { console.log('No file selected.'); } } removeImage(): void { this.selectedFile = null; this.imageUrl = null; this.categoryForm.patchValue({ icon: null }); if (this.fileInputRef) { this.fileInputRef.nativeElement.value = ''; } } triggerFileInput(): void { this.fileInputRef.nativeElement.click(); } onSubmit(): void { if (this.categoryForm.invalid) { console.error('Form is invalid'); return; } const formData = new FormData(); formData.append('name', this.categoryForm.get('name')?.value); if (this.selectedFile) { formData.append('icon', this.selectedFile); console.log("Appending new file:", this.selectedFile.name); } else if (!this.categoryId) { console.error('No file selected!'); return; } console.log("Submitting form data:", formData); if (this.categoryId) { this.httpService.put(`categories/${this.categoryId}`, formData).subscribe({ next: (response) => { console.log('Category updated successfully:', response); this.router.navigate(['category/category-list']); }, error: (error) => { console.error('Error updating category:', error); } }); } else { this.httpService.post('categories', formData).subscribe({ next: (response) => { console.log('Category added successfully:', response); this.router.navigate(['category/category-list']); }, error: (error) => { console.error('Error adding category:', error); } }); } } getCategoryDetails(categoryId: string): void { this.httpService.get<any>(`categories/${categoryId}`).subscribe({ next: (response) => { console.log('Fetched Category:', response); const category = response.data.categoryByID; this.categoryForm.reset(); this.categoryForm.patchValue({ name: category.name, icon: category.image }); this.imageUrl = category.image; this.cdr.detectChanges(); }, error: (error) => { console.error('Error fetching category:', error); } }); } } When I click the edit button and update the category name (without changing the image), the PUT request is made and the API returns a successful update. However, the table that lists the categories does not reflect the updated category name until I refresh the page manually. When I click the edit button and update the category name (without changing the image), the PUT request is made and the API returns a successful update. However, the table that lists the categories does not reflect the updated category name until I refresh the page manually. Continue reading...