So I have two components the add-contact-component (child component) and the contact-manager-component(parent component) How can I use output and event emitter for my object array to be pass from child to parent component whenever I press the update button? Also is there a way for the create button to be changed to update button whenever I click the edit button on the parent component?
Child Component
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MyContact } from '../models/myContact';
import { ContactService } from '../services/contact.service';
@Component({
selector: 'app-add-contact',
templateUrl: './add-contact.component.html',
styleUrls: ['./add-contact.component.css']
})
export class AddContactComponent implements OnInit {
public loading:boolean = false;
@Input() contact:MyContact = {} as MyContact;
@Output() contactChange:EventEmitter<MyContact> =new EventEmitter<MyContact>();
public editMode:boolean = false;
constructor(private contService:ContactService, private router:Router) { }
ngOnInit(): void {}
onSubmit(contactForm: { value: any; }) {
this.contService.CreateContacts(this.contact).subscribe((data:MyContact)=>{
this.router.navigate(['/']).then(()=>{
window.location.reload();
});
}
update() {
this.contactChange.emit(this.contact);
}
}
<div class="container">
<div class="row">
<div class="col-sm-4">
<form (ngSubmit)="onSubmit(contactForm)" #contactForm="ngForm" novalidate #contactChange>
<div class="mb-2">
<input required [(ngModel)]="contact.name" name="name" type="text" class="form-control" placeholder="Name (required)" #name="ngModel" spellcheck="false">
</div>
<div *ngIf="!name?.valid && (name?.dirty || name?.touched)">Name Required</div>
<div class="mb-2">
<input required email [(ngModel)]="contact.email" name="email" type="email" class="form-control" placeholder="Email (required)" #email="ngModel" spellcheck="false">
</div>
<div *ngIf="!email?.valid && (email?.dirty || email?.touched)">Email Not Valid</div>
<div class="mb-2">
<input required [(ngModel)]="contact.mobile" name="mobile" type="number" class="form-control" placeholder="Mobile (required)" #mobile="ngModel" spellcheck="false">
</div>
<div *ngIf="!mobile?.valid && (mobile?.dirty || mobile?.touched)">Mobile Required</div>
<div class="mb-2">
<input [(ngModel)]="contact.company" name="company" type="text" class="form-control" placeholder="Company (optional)" spellcheck="false">
</div>
<div class="mb-2">
<input [(ngModel)]="contact.title" name="title" type="text" class="form-control" placeholder="Title (optional)" spellcheck="false">
</div>
<div class="mb-2">
<input [(ngModel)]="contact.photo" name="photo" type="text" class="form-control" placeholder="Photo Url (optional)" spellcheck="false">
</div>
<div class="mb-2">
<button type="submit" class="btn btn-success" [disabled]="!contactForm.valid">Create</button>
</div>
<div class="mb-2">
<button (click)="update()" class="btn btn-primary" >Update</button>
</div>
</form>
</div>
</div>
</div>
Parent Component
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MyContact } from '../models/myContact';
import { ContactService } from '../services/contact.service';
@Component({
selector: 'app-contact-manager',
templateUrl: './contact-manager.component.html',
styleUrls: ['./contact-manager.component.css']
})
export class ContactManagerComponent implements OnInit {
public loading:boolean = false;
public contacts:MyContact[] = [];
public contactId:string | null = null;
selectedContact:MyContact = new MyContact();
constructor(private contService:ContactService, private router:Router, private activatedRoute:ActivatedRoute) { }
ngOnInit(): void {
this.getAllContactData();
}
getAllContactData(){
this.loading = true;
this.contService.getAllContacts().subscribe((data:MyContact[])=>{
this.contacts = data;
this.loading = false;
})
}
deleteContact(contactId:string | undefined){
if(contactId){
this.contService.deleteContacts(contactId).subscribe((data:{})=>{
this.getAllContactData();
});
}
}
showDetails(contact:MyContact) {
this.selectedContact=Object.assign({},contact)
this.isupdate = true;
console.log(this.isupdate);
console.log(this.selectedContact);
}
update(contact: MyContact) {
*INSERT FUNCTION HERE FOR contact to be send to the array object MyContact in parent component*
}
}
<app-add-contact [contact]="selectedContact" (contactChange)="update($event)" *ngIf="visible "></app-add-contact>
<div class="container mt-3">
<h2>Contact List</h2>
<table class="table table-bordered border-secondary border-5 table-light table-hover">
<thead class="table table-bordered table-dark">
<tr>
<th>#</th>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Contact</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let contact of contacts ; let i = index">
<td>{{ i + 1 }}</td>
<td>{{ contact.id }}</td>
<td>{{ contact.name }}</td>
<td>{{ contact.email }}</td>
<td>{{ contact.mobile }}</td>
<td><div class="d-flex align-items- justify-content-around">
<a routerLink="/contacts/view/{{contact.id}}" class="btn btn-warning my-1" data-toggle="tooltip" data-placement="top" title="View Contact Details">
<i class="fa fa-eye"></i>
</a>
<button class="btn btn-primary my-1" data-toggle="tooltip" data-placement="top" title="Edit Contact" (click)="showDetails(contact)">Edit</button>
<a routerLink="/contacts/edit/{{contact.id}}" class="btn btn-primary my-1" data-toggle="tooltip" data-placement="top" title="Edit Contact">
<i class="fa fa-pen"></i>
</a>
<button class="btn btn-danger my-1" data-toggle="tooltip" data-placement="top" title="Delete Contact" (click)="deleteContact(contact.id)">
<i class="fa fa-trash"></i>
</button>
</div></td>
</tr>
</tbody>
</table>
</div>
I've been stuck on this one for a few days already.
Tried to follow this tutorial still to no avail. Kept getting errors and data not reflecting. Angular @input, @output & EventEmitter
