Angular Router. Keep state between childrens, event user inputs

49 views Asked by At

I'm using Angular 16. I have a parent componente: ComponentA with route '/parent-component/:customId'. ComponentA has two child routes: ChildComponent1 with route '/child1' and ChildComponent2 with route '/child2'.

ComponentA has two links and router-outlet, as follow:

<a routerLink="child1">Child1</a>
<a routerLink="child2">Child2</a>
<router-outlet></router-outlet>

ChildComponent1 first call an API, after create a dynamic form.

When the user navigate to child1, fill the form and go to child2 and come back to child1, the child1 load all again (call the API and recreate dynamic form), and the user lost his work. So I want preserve the user inputs and I don't want call the and create the dynamic form again.

Is there a way that persist the child1 state, even what the user wrote in the form entries?

1

There are 1 answers

0
Junaid Firdosi On

Since you are using router-outlet, you can't use the parent component to preserve state but anyways it's better to use a Behavior Subject Inside a Shared Service to manage the state between sibling components

so the service file would be like


export class CompAService {
  private formState$: BehaviorSubject<YourFormInterface | undefined> = new BehaviorSubject(undefined);

  constructor() { }

  getFormState() : Observable<YourFormInterface> {
    return this.formState$.asObservable()
  }
  
  updateFormState(state:YourFormInterface): void {
     this.formState$.next(state)
  }
}

And in Component1 ts file, you will subscribe to the get the form state everytime the component loads into view, if the component got loaded the first time you will receive 'undefined' in your subscription and you can call the API to fetch whatever data you need for you state


@Component({
  selector: '...',
  templateUrl: '...',
  styleUrls: ['...']
})
export class Child1Component {
  form: FormGroup = new FormGroup() // your form group

  constructor(private compAService:CompAService, private destroyRef:DestroyRef){}

  ngOnInit():void{
    this.compAService.getFormState().pipe(takeUntilDestroyed(this.destroyRef))
    .subscribe(state=>{
       if (!state) {
         this.setFormState()
       }else {
         this.form.patchValue(...state) // set all your values to the form 
       }
    })
  }

  setFormState():void {
    // on receiving your response from api call OR receiving values from your 
    // html form, set the state so you get it the next time
    this.compAService.updateFormState(state)
  }
}