I have 2 files that load data into 1 page. I want the content of component B to get loaded when components of component A are being loaded onto the page.
Component A.
ngOnInit(): void {
this.route.queryParams
.pipe(
first(),
tap(
(params) =>
(this.params = params?.filters ? JSON.parse(params.filters) : {})
),
switchMap(() =>
this.http
.get(
this.configPrv.AppSetting.uriReports
.getReportsDashboardConfig,
{
withCredentials: true,
}
)
.pipe(
tap(
(response: {
fields: FieldsDefinition<Form>;
dimensions?: string;
}) => {
this.form = this.formGenerator.init(
{
layout: {
'grid-template-columns': '1fr 1fr 1fr 1fr',
'column-gap': '1.5em',
},
fields: response.fields,
},
this.params
);
}
),
switchMap(() =>
this.form.values$.pipe(
tap(
(values: Form) =>
(this.reportEndpoint = values?.report || '')
),
tap((filters) =>
this.router.navigate(['./'], {
relativeTo: this.route,
queryParams:
Object.keys(filters).length !== 0
? { filters: JSON.stringify(filters) }
: {},
})
)
)
)
)
),
takeUntil(this._onDestroySubject)
)
.subscribe();
}
Component B
ngOnInit(): void {
this.http
.get<ReportBuilderReportConfig>(
this.configPrv.AppSetting.uriReports.getReportsDashboardConfig,
{ withCredentials: true }
)
.pipe(tap((response) => {}))
.subscribe((resp) => {});
}
When the page is loaded, contents of component A are loaded but I want to have contents of component B load as well.
When component A has finished loading Component B (if it's a child) will automatically get triggered.
My understanding is that you are making the API call on componentA, but you are making the same API call on component B, since it's already made in A, you want to pass the response to ComponentB.
There are two ways to do this.
You can use @Input
and pass the data through HTML (create a new property and store the response from API if needed) before passing to component B:
<app-componentb [response]="response" [form]="form"/>
TS:
@Component({...}
export class ComponentB {
@Input() response: any;
@Input() form: any;
Another way is to use a common service, ng g c CommonService
, ensure you have providedIn: 'root'
in the injector object
@Injector({
providedIn: 'root'
})
export class CommonService {
response: any;
form: any;
}
Then on the parent, assign the data you need to the service
Component A
@Component({...})
export class ComponentA {
constructor(private commonService: CommonService) {}
ngOnInit(): void {
...
(response: {
fields: FieldsDefinition<Form>;
dimensions?: string;
}) => {
this.response = this.commonService.response = response;
this.form this.commonService.form = this.formGenerator.init(
{
layout: {
'grid-template-columns': '1fr 1fr 1fr 1fr',
'column-gap': '1.5em',
},
fields: response.fields,
},
this.params
);
}
),
Component B:
@Component({...})
export class ComponentB {
constructor(private commonService: CommonService) {}
ngOnInit(): void {
console.log(this.commonService.response);
// do something with the data!
}
...