Reuse component in another component and get the data of the child in Angular

1

I made a ZIP search component this way:

I created the component, its HTML is:

<fieldset [disabled]="isLoading">
    <div class="row col-md-6">
        <div class="row">
            <div class="col-md-4">
                <div class="form-group">
                    <label for="cep">CEP</label>
                    <input type="text" class="form-control" id="cep" placeholder="00000-000" [(ngModel)]="cep.cep" />
                </div>
            </div>
            <div class="col-md-8">
                <button class="btn btn-primary" type="button" (click)="buscar()" [disabled]="isLoading">Buscar</button>
            </div>
        </div>
        <div class="row">
            <div class="col-md-8">
                <div class="form-group">
                    <label for="logradouro">Logradouro</label>
                    <input type="text" class="form-control" id="logradouro" placeholder="Logradouro" [(ngModel)]="cep.logradouro" />
                </div>
            </div>
            <div class="col-md-4">
                <div class="form-group">
                    <label for="numero">Número</label>
                    <input type="text" class="form-control" id="numero" placeholder="Numero" [(ngModel)]="cep.numero" />
                </div>
            </div>
        </div>
        <div class="form-group">
            <label for="complemento">Complemento</label>
            <input type="text" class="form-control" id="complemento" placeholder="complemento" [(ngModel)]="cep.complemento" />
        </div>
        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label for="cidade">Cidade</label>
                    <input type="text" class="form-control" id="cidade" placeholder="Cidade" [(ngModel)]="cep.cidade" />
                </div>
            </div>
            <div class="col-md-6">
                <div class="form-group">
                    <label for="bairro">Bairro</label>
                    <input type="text" class="form-control" id="bairro" placeholder="Bairro" [(ngModel)]="cep.bairro" />
                </div>
            </div>
        </div>
        <div class="form-group">
            <label for="estado">Estado</label>
            <input type="text" class="form-control" id="estado" placeholder="Estado" [(ngModel)]="cep.estado" />
        </div>
    </div>
</fieldset>

Your component.ts is:

import { Component, OnInit } from '@angular/core';
import {CepService} from '../../services/cep/cep.service';
import {Cep} from '../../cep';

@Component({
  selector: 'cep',
  templateUrl: './cep.component.html',
  styleUrls: ['./cep.component.css']
})
export class CepComponent implements OnInit {

  cep = new Cep();
  isLoading = false;

  constructor(private cepService: CepService) { }

  ngOnInit() {

  }

  buscar() {
    this.isLoading = true;
    this.cepService.buscar(this.cep.cep)
    .then((cep: Cep) => {
      this.isLoading = false;
      this.cep = cep;
    })
    .catch(() => {
      this.isLoading = false;
      const cep = this.cep.cep;
      this.cep = new Cep();
      this.cep.cep = cep;
      alert('Não possível continuar a busca');
    })
  }
}

And I created a Service to fetch from an API:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import {Cep} from './../../cep';
import 'rxjs';

@Injectable()
export class CepService {

    constructor(private http:Http) { }

    buscar(cep:string){
        return this.http.get('https://viacep.com.br/ws/${cep}/json/')
            .toPromise()
            .then(response => this.converterRespostaParaCep(response.json()));
    }

    private converterRespostaParaCep(cepNaResposta):Cep{
        let cep = new Cep();
        cep.cep = cepNaResposta.cep;
        cep.logradouro = cepNaResposta.logradouro;
        cep.complemento = cepNaResposta.complemento;
        cep.bairro = cepNaResposta.bairro;
        cep.cidade = cepNaResposta.localidade;
        cep.estado = cepNaResposta.uf;
        return cep;
    }
}

And a zip.ts file at the root with the fields:

export class Cep{
    cep:string;
    logradouro:string;
    numero:string;
    complemento:string;
    cidade:string;
    bairro:string;
    estado:string;
}

It works perfect.

However, how do I reuse this zip code search component in other forms, taking the results of the zip search and playing to the other forms?

Type, I have my form, I put <cep></cep> and it incorporates my zip search component, ok!

        telephone                                    
<cep></cep>

<div class="form-group row">
    <label for="inputEmail3" class="col-sm-2 col-form-label">IDPoker</label>
    <div class="col-sm-10">
        <input type="text" class="form-control" id="idpoker" name="idpoker" placeholder="IDPoker" [(ngModel)]="jogador.idpoker" required>
    </div>
</div>

Here on this form I have your TS like this here:

import { Component, OnInit } from '@angular/core';
import { JogadorService } from './../../services/jogador.service';
import { Router, ActivatedRoute } from '@angular/router';
import { MessageService } from '../../services/message.service';

@Component({
  selector: 'app-jogador-form',
  templateUrl: './jogador-form.component.html',
  styleUrls: ['./jogador-form.component.css']
})
export class JogadorFormComponent implements OnInit {

  jogador = {
    id: null,
    nome: '',
    email: '',
    cpf: '',
    celular: '',
    telefone: '',
    idpoker: '',
    nickpoker: '',
    foto: '',
    usuario: '',
    senha: ''
  };

  constructor(private jogadorService: JogadorService,
    private router: Router,
    private route: ActivatedRoute,
    private messageService: MessageService) { }

  ngOnInit() {
    console.log('id');
    this.route.params.subscribe(params => {
      if(params.hasOwnProperty('id')){
        this.jogadorService.find(params['id'])
        .subscribe(data => this.jogador = data);
      }
    });
  }

  save() {
    console.log(this.jogador);
    this.jogadorService.save(this.jogador)
        .subscribe(() => {
            this.messageService.message = 'Jogador cadastrado com sucesso.';
            alert('pasou aqui');
            // this.router.navigate(['/posts'])
        });
}

}

How do I actually re-use the ZIP code search component in my form and save my ZIP code component data to my API?

Thank you.

    
asked by anonymous 25.11.2018 / 18:14

1 answer

1

You can use @Output together with EventEmitter and "publish" your new data to whoever uses the component. On your CepComponent create the property:

@Output() cepResult: EventEmitter<Cep> = new EventEmitter();

And when you get the value:

this.cepService.buscar(this.cep.cep)
 .then((cep: Cep) => {
   this.isLoading = false;
   this.cep = cep;
   // você está emitindo o novo valor
   this.cepResult.next(cep);
})

And in components that use their <cep></cep , in HTML:

<cep (cepResult)="metodoParaPegarOValor($event)"></cep>

And no .ts :

metodoParaPegarOValor(event) {
   // valor atualizado
   console.log(event);
}
    
26.11.2018 / 13:45