Calling a function between components - angular6

I have two components(comp1 and comp2). I am trying to call a function which is inside comp1 from comp2 and it is not happening and it is throwing an error. But it is successful when calling a function inside comp2 from comp1.
I want it to happen in both the ways
(i.e)
(a) function trigger from comp2 inside comp1
(b)function trigger from comp1 inside comp2
I have attached the sample code.
https://stackblitz.com/edit/angular-jxfzqb

The error is throwing from constructor function on comp1, it cant generate a new instance of comp2.
Please try not use provides of components between components, i suggest you make getting binding components from app.component to comp1 and comp2, example:
app.component.html
<app-comp1 #comp1 [Comp2Component]="comp2"></app-comp1>
<app-comp2 #comp2 [Comp1Component]="comp1"></app-comp2>
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Comp1Component } from './comp1/comp1.component';
import { Comp2Component } from './comp1/comp2/comp2.component';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
// Get component with attr #comp1
#ViewChild('comp1') comp1: Comp1Component;
// Get component with attr #comp2
#ViewChild('comp2') comp2: Comp2Component;
}
comp1.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-comp1',
templateUrl: './comp1.component.html',
styleUrls: ['./comp1.component.css']
})
export class Comp1Component implements OnInit {
#Input() Comp2Component: Comp2Component;
constructor() { }
ngOnInit() {
}
funcInComp1() {
console.log("comp1 function triggered from comp2");
}
triggerComp2Function() {
this.Comp2Component.funcInComp2();
}
}
comp2.component.ts
import { Input, Component, OnInit } from '#angular/core';
import { Comp1Component } from '../comp1.component';
#Component({
selector: 'app-comp2',
templateUrl: './comp2.component.html',
styleUrls: ['./comp2.component.css']
})
export class Comp2Component implements OnInit {
#Input() Comp1Component: Comp1Component
constructor() { }
ngOnInit() {
}
triggerComp1Function() {
this.Comp1Component.funcInComp1();
}
funcInComp2() {
console.log("comp2 function triggered from comp1");
}
}
stackblitz:
https://stackblitz.com/edit/angular-itmzhe

Related

How to get the selected value from one component to other using event emitter in angular 8

I have 2 components , one login and other home. When I change drop down into login component ,selected value need to display in home component. I am already emitting the onchange event from login component to home component and displaying the value but still I am not getting the value into home component.Here is the code below
login.component.html
<select #mySelect (change)="onOptionsSelected(mySelect.value)">
<option value="one">one</option>
<option value="two">two</option>
</select>
login.component.ts
import { Component, OnInit,Input,Output, EventEmitter } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
#Output() buttonClicked = new EventEmitter();
constructor(private router: Router) { }
#Input() item: string;
ngOnInit() {
}
onOptionsSelected(value:string){
console.log("the selected value is " + value);
this.buttonClicked.emit(value);
this.router.navigateByUrl('/home');
}
}
home.component.html
<p>home works!</p>
<app-login (buttonClicked)='showNextComponent($event)'></app-login>
<p>Hello {{ name }} </p>
home.component.ts
import { Component, OnInit,ElementRef,ViewChild } from '#angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
import { LoginComponent } from '../login/login.component';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
getListData: any;
constructor(private commonserviceService: CommonserviceService) { }
name:string
ngOnInit() {
}
showNextComponent(value:string) {
this.name = value;
console.log(this.name);
}
}
I pasted your code here in stackblitz: https://stackblitz.com/edit/angular-cfkqns
You are correctly emitted values up to the parent component and binding the value to be displayed in the parent component.
It is working how you expect it to :-)
UPDATE:
I have answered the same question for some one else here:
https://stackoverflow.com/a/64082745/450388
however I have updated your stackblitz to reflect how to achieve the same.
https://stackblitz.com/edit/angular-cfkqns

Display data from json array using angular4

I am new to angular so please help me. I have an api returning an array of objects containing name, place id.
I need to display this in different cards on my html page, the cards being a widget.
in the parent component under the ngOnInit() section how do I access this json data and loop through the array in order to display it on my page as different cards?
Thank you in advance.
import { Component, OnInit } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import { Observable } from 'rxjs/observable';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
showSplash = true
//public events: any = [];
events = [];
constructor(private http : HttpClient) { }
ngOnInit() {
this.showSplash = true
this.http.get("/events").subscribe(data => {
console.log("EVENTS ARE: ", data);
this.events = data;
console.log(this.events)
})
}
ngAfterViewInit(){
setTimeout(() => {
this.showSplash = false
}, 3000);
}
}
This will get you the events you want.
import { Component, OnInit, OnDestroy } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Subscription } from 'rxjs';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit, OnDestroy {
showSplash = true
events = [];
subscription: Subscription;
constructor(private http: HttpClient) {}
ngOnInit() {
this.subscription = this.http.get("/events").subscribe(data => {
this.events = data;
this.showSplash = false;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
You will have to implement a Child Component(EventComponent probably with the selector app-event) that will accept an event object as an #Input property. Then in your HomePageComponent Template, you can loop through the events like this:
<div *ngFor="let event of events">
<app-event [event]="event"></app-event>
</div>
Alternatively:
You can use the async pipe in your HomePageComponent's Template to avoid manually unsubscribing from the Observable Subscription. Your HomePageComponent Class code will change to:
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
events$;
constructor(private http: HttpClient) {}
ngOnInit() {
this.events$ = this.http.get("/events");
}
}
And then in HomePageComponent's Template:
<div *ngFor="let event of events$ | async">
<app-event [event]="event"></app-event>
</div>
Here's how your EventComponent would look like in this case:
import { Component, Input, OnChanges } from '#angular/core';
#Component({
selector: 'app-event',
templateUrl: './event.component.html',
styleUrls: ['./event.component.css']
})
export class EventComponent implements OnChanges{
#Input() event;
ngOnChanges() {
this.events$ = this.http.get("/events");
}
}

Adding a component into a div

I am trying to create a div and then add a component into that div during runtime. I was wondering how i could do this.
this is my components html:
<p>
<label >name</label>
</p>
this is my components ts :
import { Component, OnInit} from '#angular/core';
#Component({
selector: 'app-newcomp',
templateUrl: './newcomp.component.html',
styleUrls: ['./newcomp.component.css']
})
export class NewcompComponent implements OnInit {
name: string;
constructor() {
}
ngOnInit() {
}
}
This is where it will be called
import { Component } from '#angular/core';
import { NewcompComponent } from './newcomp/newcomp.component';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor() {
this.Newcomp();
}
Newcomp() {
const div = document.createElement('div');
document.body.appendChild(div);
<-- this is where the component is added to the div, how can i achieve this.
}
}
If someone could help me it would be greatly appreciated. :)
Also i know this example is simple, but keeping it simple will allow for clarity in the answer.
import { Component } from '#angular/core';
import { NewcompComponent } from './newcomp/newcomp.component';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
component: Type<any>;
constructor() {
this.component = this.newcomp();
}
private newcomp() {
// use this method for logic
return NewcompComponent;
}
}
In app.component.html add:
<ng-container *ngComponentOutlet="component"></ng-container>
For more info Angular's component outlet info & Angular's dynamic component creation

Angular 2/4: Can't update child component view

I want to update the value of str which I used in the view of child component from the parent component, by calling the function change() of child component
here is my code.
import { Component } from '#angular/core';
import { ChildComponent } from './child/child.component';
#Component({
selector: 'app-root',
template: `
<h1>parent</h1>
<button (click)="changeChild()">change child</button>
<app-child></app-child>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private cc:ChildComponent) {}
changeChild(){
this.cc.change();
}
}
and the child component is:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-child',
template: `
<p>{{str}}</p>
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
private str;
constructor() {
this.str = 'initial'
}
change(){
this.str = 'changed'
}
ngOnInit() {
}
}
but the value str in the view never updated to "changed".
please Any help because I am new in Angular 4 ??
Use #ViewChild to get reference of child component
in Parent component
import {ChildComponent} from 'child.component.ts'
export class ParentComponent{
------
#ViewChild(ChildComponent)
private child:ChildComponent
---
changeChild(){
this.child.change()
}
}

how can i pass value from child to parent component in angular 2?

I need to get data from child component. My child component has form which is in popu. How can i pass full details to parent component.
my parent component ts file is
import { Component, OnInit } from '#angular/core';
import {MdDialog, MdDialogRef} from '#angular/material';
#Component({
selector: 'app-vehicle-relocate',
templateUrl: './vehicle-relocate.component.html',
styleUrls: ['./vehicle-relocate.component.css'],
})
export class VehicleRelocateComponent implements OnInit {
lat: number = 11.074529;
lng: number = 78.003917;
zoom: number = 14;
ngOnInit() {
}
selectedOption: string;
constructor(public dialog: MdDialog) {}
openDialog() {
let dialogRef = this.dialog.open();
dialogRef.afterClosed().subscribe(result => {
this.selectedOption = result;
});
}
}
My child component is in parent component
import { Component, OnInit, Input } from '#angular/core';
import {MdDialog, MdDialogRef} from '#angular/material';
#Component({
selector: 'app-relocate-form',
templateUrl: './relocate-form.component.html',
styleUrls: ['./relocate-form.component.css']
})
export class RelocateFormComponent implements OnInit {
constructor(public dialogRef: MdDialogRef<RelocateFormComponent>) {}
#Input() title:string;
ngOnInit() {
}
}
You can add an Output to your child component.
For example: #Output() notifySubmit : EventEmitter<any> = new EventEmitter<any>()(you can put whatever type you want if you don't want 'any').
Then when you're submitting the form in your child component, you have to notify the parent with the Output:
this.notifySubmit.emit(myValues)
Now you have to receive the event in the parent component. When you call your RelocateFormComponent from VehicleRelocateComponent you need to pass a function to the Output.
<app-relocate-form (notifySubmit)="myFunction($event)" ... ></app-relocate-form>
myFunction($event)has to be in the parent component. The $event parameter equals to what you sent with this.notifySubmit.emit(myValues).