Is it correct inject Component in another Component to access functions or properties in injected Component?
Notice: None of these components is a child of another
import { UsersComponent } from './../users/users.component';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(users:UsersComponent){
users.getAllUsers()
}
}
You can't actually do it this way. In Angular, we think everything as a component wise. If any method or property is used by multiple component you can follow below methods. As your components are not related as child parent. you can follow 3 and 4 Methods.
1. Parent to Child and Child to Parent: Sharing Data via @Input and @Output
This is most frequently used way of sharing data between components. It uses @Input() decorator. You can also use @Output() decorator to event pass to the parent.
parent.component.ts:
@Component({
selector: 'app-parent',
template: `
<p>{{ message }}</p>
<app-child [input]="parentData" (output)="childMsg($event)"></app-child>`
})
export class ParentComponent{
message: string;
parentData = "message from parent"
childMsg(event) {
this.message = event;
}
}
child.component.ts:
@Component({
selector: 'app-child',
template: `
<p>{{ input }}</p>
<button (click)="submit()">Submit</button>
`
})
export class ChildComponent {
@Input() input: string;
@Output() output = new EventEmitter<string>();
message: string = "Hello World!"
submit() {
this.output.emit(this.message)
}
}
2. Child to Parent: Sharing Data via ViewChild
@ViewChild decorator allows a one component to be injected into another, giving the parent access to its properties and methods.
parent.component.ts
@Component({
selector: 'app-parent',
template: `
Message: {{ childData }}
<app-child></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) child;
childData: string;
ngAfterViewInit() {
this.childData = this.child.message
}
}
child.component.ts:
@Component({
selector: 'app-child',
})
export class ChildComponent {
childData = 'Hola Mundo!';
}
N.B: we use AfterViewInit lifeCycle because the child wasn't available until the view is initialized.
3. Unrelated Components using Service: Sharing Data between unrelated components with a Service and Behavior Subject
common.service.ts:
@Injectable()
export class CommonService {
private data = new BehaviorSubject('default data');
data$ = this.data.asObservable();
changeData(data: string) {
this.data.next(data)
}
}
component-one.component.ts:
@Component({
selector: 'app-component-one',
template: `<p>{{data}}</p>`
})
export class ComponentOneComponent implements OnInit {
data: string;
constructor(private service: CommonService) { }
ngOnInit() {
this.service.data$.subscribe(res => this.data = res)
}
}
component-two.component.ts:
@Component({
selector: 'app-component-two',
template: `
<p>{{data}}</p>
<button (click)="newData()">Next Data</button>`
})
export class ComponentTwoComponent implements OnInit {
data: string;
constructor(private service: CommonService) { }
ngOnInit() {
this.service.data$.subscribe(res => this.data = res)
}
newData() {
this.service.data.next('Changed Data');
}
}
4. State Management: Share data between unrelated components using NgRx You can use store like NgRx to manage state where you will store your property then use everywhere. Example I followed this example when learning ngrx.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With