Newly Added Tasks Not Rendering Automatically

Discussão em 'Angular' iniciado por Ahmad Irshad, Outubro 15, 2024.

  1. Ahmad Irshad

    Ahmad Irshad Guest

    I am learning Angular for now I am practicing on a CRUD app, where I can add, edit, and delete tasks. I'm using standalone components and a service to manage tasks and their state. I have implemented a BehaviorSubject to hold the task list and update the UI. However, newly added tasks do not render automatically on the UI after they are added; instead, I have to refresh the page to see the updates. If anyone can help me with it.

    Code in Service

    import { Injectable } from '@angular/core';
    import { BehaviorSubject, Observable } from 'rxjs';
    import { HttpClient } from '@angular/common/http';
    import { taskType } from './taskType';
    import { tap } from 'rxjs/operators';

    @Injectable({
    providedIn: 'root'
    })
    export class TaskServiceService {
    private url: string = 'http://localhost:3000/tasks';
    private taskSubject = new BehaviorSubject([]); // Initializing BehaviorSubject

    public tasks$ = this.taskSubject.asObservable(); // Expose the observable

    constructor(private http: HttpClient) {}

    fetchTasks() {
    return this.http.get(this.url).subscribe({
    next: (data: taskType[]) => {
    this.taskSubject.next(data);
    },
    error: (error) => {
    this.taskSubject.error(error);
    }
    });
    }

    addTask(newTask: taskType): Observable {
    return this.http.post(this.url, newTask).pipe(
    tap((task: taskType) => {
    const updatedTasks = [...this.taskSubject.value, task]; // Update with new task
    this.taskSubject.next(updatedTasks); // Notify observers
    })
    );
    }

    // Other methods for deleting and updating tasks...
    }


    Code in table component where I a displaying tasks:

    import { Component, OnInit } from '@angular/core';
    import { TaskServiceService } from '../../task-service.service';
    import { taskType } from '../../taskType';
    import { CommonModule } from '@angular/common';

    @Component({
    selector: 'app-table-sub',
    standalone: true,
    imports: [CommonModule],
    templateUrl: './table-sub.component.html',
    styleUrl: './table-sub.component.css',
    providers:[]
    })
    export class TableSubComponent implements OnInit {
    constructor(private taskObj: TaskServiceService){}

    AllTasks: taskType[]=[]

    ngOnInit(){
    this.taskObj.tasks$.subscribe(data => {
    console.log("new task obj", data)
    this.AllTasks = data; // Update local tasks array whenever there's a change
    });
    this.taskObj.fetchTask();
    }

    }


    Code in Form Component

    import { Component } from '@angular/core';
    import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
    import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
    import { TaskServiceService } from '../../task-service.service';
    import { taskType } from '../../taskType';
    import { HttpClientModule } from '@angular/common/http';

    @Component({
    selector: 'app-form-sub',
    standalone: true,
    imports: [ReactiveFormsModule],
    templateUrl: './form-sub.component.html',
    styleUrl: './form-sub.component.css',
    providers:[]
    })
    export class FormSubComponent {
    constructor(public activeModal: NgbActiveModal,private taskObj: TaskServiceService) {}

    myFormGroup!: FormGroup

    ngOnInit(){
    this.formInit()
    }


    formInit(){
    this.myFormGroup = new FormGroup({
    title: new FormControl('',Validators.required),
    description: new FormControl('',Validators.required),
    status: new FormControl('',Validators.required)
    })
    }



    onSubmit(myForm: FormGroup){
    this.taskObj.addTask(myForm.value).subscribe({
    next: (data)=>{
    this.taskObj.updateTasks([data])

    },error:(error)=>{
    console.log("some error occured", error)
    }
    })

    }

    }


    Code in View Part of Form Component

    <div class="modal-dialog">
    <div class="modal-content bg-dark text-white"> <!-- Dark background and white text -->
    <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Add Task</h4>
    <button type="button" class="btn-close" aria-label="Close" (click)="activeModal.dismiss('Cross click')"></button>
    </div>
    <div class="modal-body">
    <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit(myFormGroup)">
    <label for="title">Title:</label>
    <input id="title" type="text" class="form-control bg-secondary text-white" formControlName="title"> <!-- Dark input field -->

    <label for="description" class="mt-2">Description:</label>
    <input id="description" type="text" class="form-control bg-secondary text-white" formControlName="description"> <!-- Dark input field -->

    <label for="status" class="mt-2">Status:</label>
    <select id="status" class="form-control bg-secondary text-white" formControlName="status">
    <option value="Pending">Pending</option>
    <option value="In Progress">In Progress</option>
    <option value="Completed">Completed</option>
    </select>
    <div class="'button-center"><button type="submit" class="btn btn-primary" >Save changes</button></div>

    </form>
    </div>
    <div class="modal-footer">
    <button type="button" class="btn btn-secondary" (click)="activeModal.dismiss()">Close</button>

    </div>
    </div>
    </div>



    Code in View part of

    <div class="modal-dialog">
    <div class="modal-content bg-dark text-white">
    <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">Add Task</h4>
    <button type="button" class="btn-close" aria-label="Close" (click)="activeModal.dismiss('Cross click')"></button>
    </div>
    <div class="modal-body">
    <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit(myFormGroup)">
    <label for="title">Title:</label>
    <input id="title" type="text" class="form-control bg-secondary text-white" formControlName="title">

    <label for="description" class="mt-2">Description:</label>
    <input id="description" type="text" class="form-control bg-secondary text-white" formControlName="description">

    <label for="status" class="mt-2">Status:</label>
    <select id="status" class="form-control bg-secondary text-white" formControlName="status">
    <option value="Pending">Pending</option>
    <option value="In Progress">In Progress</option>
    <option value="Completed">Completed</option>
    </select>
    <div class="'button-center"><button type="submit" class="btn btn-primary" >Save changes</button></div>

    </form>
    </div>
    <div class="modal-footer">
    <button type="button" class="btn btn-secondary" (click)="activeModal.dismiss()">Close</button>

    </div>
    </div>
    </div>



    Code in .ts file of Main Component

    import { Component } from '@angular/core';
    import { RouterOutlet } from '@angular/router';
    import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
    import { FormSubComponent } from './components/form-sub/form-sub.component';
    import { TableSubComponent } from './components/table-sub/table-sub.component';
    import { HttpClientModule } from '@angular/common/http';
    import { TaskServiceService } from './task-service.service';


    @Component({
    selector: 'app-root',
    standalone: true,
    imports: [RouterOutlet,FormSubComponent,TableSubComponent],
    templateUrl: './app.component.html',
    styleUrl: './app.component.css',
    providers:[TaskServiceService]
    })
    export class AppComponent {
    title = 'todo2';
    constructor(private modalService: NgbModal) {}

    openModal() {
    const modalRef = this.modalService.open(FormSubComponent);
    modalRef.componentInstance.title = 'Hello'; // If you want to pass data to the modal
    }

    }


    Code in View Part of Main Component

    <div class="btn-div">
    <button type="button" class="btn btn-primary" (click)="openModal()">Open Modal</button>
    </div>

    <app-table-sub></app-table-sub>



    taskType interface

    export interface taskType {
    id: string,
    title: string,
    description: string,
    status: string
    }


    JSON server file

    {
    "tasks": [
    {
    "title": "Update rendering issues",
    "description": "Not updating while immediately after task is added and correct working",
    "status": "Pending",
    "id": "cf5e50a5-9c04-488b-a2e5-c050583a3722"
    },
    {
    "id": "2923",
    "title": "new Task",
    "description": "new",
    "status": "In Progress"
    }
    ]
    }


    I want whenever a new task is added it should be rendered to UI without refreshing the page

    Continue reading...

Compartilhe esta Página