Q:

The best approach to call APIs when init a form

I have a page like this:

Parent Component

1st Child Component:

Call API to get Countries
Call API to get Addresses

2nd Child Component

Call API to get Countries      

3rd Child Component      

Call API to get Addresses

I think there are two ways:

Call all APIs in the Parent Component, then transfer data to the Child Components
Call API in the Child Component

Which way is better way to call the same API in child components when init a form in parent component using Angular Observable?

A:

For data that does not change very often, such as a list of countries, your service can retain the set of values.
Something like this (which retains products, but you can change it for countries):
@Injectable()
export class ProductService {
    private productsUrl = 'api/products';
    private products: IProduct[];

    constructor(private http: HttpClient) { }

    getProducts(): Observable<IProduct[]> {
        if (this.products) {
            return of(this.products);
        }
        return this.http.get<IProduct[]>(this.productsUrl)
                        .pipe(
                            tap(data => this.products = data),
                            catchError(this.handleError)
                        );
    }
}

You can find the complete code for this example here: 
https://github.com/DeborahK/Angular-Communication
Then the data is only retrieved one time and the child components calling this same method get the data already retrieved.
Another option is to use a resolver in the parent component. The data from the resolver is then automatically available to the children.
@Injectable()
export class ProductResolver implements Resolve<IProduct[]> {

    constructor(private productService: ProductService,
                private router: Router) { }

    resolve(route: ActivatedRouteSnapshot,
            state: RouterStateSnapshot): Observable<IProduct[]> {
        return this.productService.getProducts();
    }
}

And then in a child component:
ngOnInit(): void {
    this.product = this.route.parent.snapshot.data['product'];
}

You can find the complete source code for this one here: 
https://github.com/DeborahK/Angular-Routing

