Best way to pass data from one component to another

Asked

Viewed 132 times

1

I have a code where a list of plans is displayed that an academy has, when clicking on one, opens a page where it chooses whether it will be (Time: quarterly, half-yearly or annual), and selects the modality (if it acts), as:

  • Plano: Martial Arts
  • Modalities: Jiu-jitsu, Self-defense, Muay thai and etc...

To choose time I opted for a Radio button and mode a checkbox.

When the person clicks on buy, goes to the purchase screen where the user will enter the data on it, card and etc...

My question is how best I pass the data of what the user chose as time and mode to the shopping page, how to traffic this data?

Page code:

page.plano.ts

  public planoId;

  private planoDados;

  vigencia: number;

  modalidades: any[] = [];

  limiteModalidades: number;

  modalidadesEscolhidas: any[] = [];

  modalidadesObrigatorias: any[] = [];

  numeroModalidadesObrigatorias: number;

  constructor(
    private planoService: PlanoService,
    private router: Router,
    private activatedRoute: ActivatedRoute
    ) {
    this.activatedRoute.params.subscribe(params => (this.planoId = params.id));
  }

  ngOnInit() {
    this.planoService.receberPlano(this.planoId).subscribe(response => {
      this.limiteModalidades = parseInt(response.Itens[0].PlanoModalidadeSelecaoLimite, 10);
      this.planoDados = response.Itens[0];
      response.Itens[0].PlanoModalidades.forEach(i => {
        this.modalidades.push(i)
      })
      this.modalidadesObrigatorias = response.Itens[0].PlanoModalidades.filter((obg) => {
        return obg.PlanoModalidadeObrigatoria === '1'
      })
      console.log(this.modalidadesObrigatorias)
      this.numeroModalidadesObrigatorias = this.modalidadesObrigatorias.length
      this.modalidadesObrigatorias.forEach(i => {
        this.modalidadesEscolhidas.push(i.PlanoModalidadeID)
      });
      this.numeroPlanosAEscolher = this.limiteModalidades - this.modalidadesEscolhidas.length
    });
  }

  valorVigencia(vigencia) {
    this.vigencia = vigencia
  }

  addModalidade(i) {
    let index = this.modalidadesEscolhidas.indexOf(i)
    if (this.modalidadesEscolhidas.length >= this.limiteModalidades) {
      this.checkboxErro = true;
    } else {
      this.checkboxErro = false;
    }
    if (index === -1) {
      this.modalidadesEscolhidas.push(i)

    } else {
      this.modalidadesEscolhidas.splice(index, 1)
    }
  }

  validar(){
    if (this.vigencia && this.modalidadesEscolhidas.length === this.limiteModalidades) {
      this.router.navigateByUrl(`./comprar/${this.planoId}/${this.vigencia}/${this.modalidadesEscolhidas}`)
    } else {
      console.log('Merda')
    }
  }
}

page.plano.html

<div>
   <label class="btn btn-outline-success col teste">
      <input #radioBox
            type="radio"
            name="options"
            (click)="valorVigencia(radioBox.value)"
            [value]="v.ItemValorID"
        />
      <span class="lead">
         {{ v?.ItemValorQuantidade | frequenciaParaRecorrencia }}
         <div>
            {{ v?.ItemValorQuantidade }}x de
            {{ v?.ItemValorPreco / v?.ItemValorQuantidade | currency: "BRL" }}
         </div>
      </span>
   </label>

    <div *ngFor="let modalidade of modalidades; let i = index">
       <label class="btn btn-outline-success col teste">
           <input #checkbox
                  type="checkbox"
                  [name]="modalidades"
                  [value]="modalidade.PlanoModalidadeID"
                  (change)="addCheckbox(checkbox.value)"
                  [checked]="modalidade.PlanoModalidadeObrigatoria === '1'"
                  [disabled]="modalidade.PlanoModalidadeObrigatoria === '1'"
            />
            <span class="lead">
               {{ modalidade?.PlanoModalidadeDescricao }}
            </span>
         </label>
      </div>

I just need to move to the purchase page the plan id planoId: number, time: vigencia: number and modalities: modalidadesEscolhidas: string[]

Help me!! If you think I need to improve the question let me know.

  • Voce can use ngrx or a behaviorsubject

3 answers

2

In Angular we have something called @Input and @Output they allow to traffic data between components for example.

Component Pai

mandafiltro: any;

this variable will receive the sample data a filter form.

Component Filho

@Input() recebeFiltro: any;

in the child component create a variable that will receive the remembering data with the @Input in front.

When to Call Html Child

when you call the html child or your componet in its tag you will have this variable that will receive a parameter as you can see in the image below

<seu-component-filho [recebeFiltro]="mandaFiltro"></seu-component-filho>

thus passing the data to the other component.

  • Please do not use code in image form

  • thanks for the tip.

2

I’m seeing that your logic is to make like a shopping cart, the best way to work with it in a scalable way is to use state management.

At first you are working with only two components, pass parameter by @Input() is a good one, but what if now you want to put an icon of a cart that stores a quantity, and that cart is in a component that is not in the tree of components that contain the plan? is in the header component for example, change this value by @Input() generates a lot of work.

The correct thing is for you to store this customer purchase data in a place where all the components that need to change/pick up this data can do it with ease. For this you use state management, in the case of angular with the ngrx. Take a look at this link has a very good explanation.

1

When the user clicks on the purchase button, you can use the Session Storage to save this information. So on the other page, you can check the value of these variables (plan and term), and make the contract.

Another approach could be to save this information to the redirect URL and the other pull page with Urlsearchparams.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.