Reputation: 169
I'm trying to make a reusable component but I can't find a way to make ngOnInit get the data depends on the component input.
Service :
export class BookService {
private apiUrl = 'http://localhost:5000/';
constructor(private http: HttpClient) {}
getBooks(): Observable<DragItem[]> {
return this.http.get<DragItem[]>(this.apiUrl + 'books');
}
getNames(): Observable<DragItem[]> {
return this.http.get<DragItem[]>(this.apiUrl + 'names');
}
}
the component :
ngOnInit(): void {
this.booksService
.getBooks() // => how can I make this dynamic depends on component props so I can pick (getBooks / getNames)
.subscribe((response) => (this.items = response));
}
Upvotes: 0
Views: 287
Reputation: 169
solved by changing the service to one method
service :
export class BookService {
private apiUrl = 'http://localhost:5000/';
constructor(private http: HttpClient) {}
getData(str: string): Observable<DragItem[]> {
return this.http.get<DragItem[]>(this.apiUrl + str);
}
}
component :
@Input() type: string = '';
@Input() methodName = '';
items: DragItem[] = [];
selectedItems: DragItem[] = [];
searchInput = new FormControl('');
page: number = 1;
pageSize: number = 10;
constructor(private booksService: BookService) {}
ngOnInit(): void {
this.booksService
.getData(this.methodName)
.subscribe((response: DragItem[]) => (this.items = response));
}
Upvotes: 0
Reputation: 461
You can use Angular's dependency providers to achieve your goal. Check details: https://angular.io/guide/dependency-injection-providers#specifying-an-alternative-class-provider
First of all we need base service:
export abstract class DataItemsService {
abstract fetch(): Observable<DataItem[]>;
}
This service needs to be injected to your reusable component:
export class FeatureComponent implements OnInit {
dataItems$: Observable<DataItem[]>;
constructor(private readonly dataItemsService: DataItemsService) {}
ngOnInit(): void {
this.dataItems$ = this.dataItemsService.fetch();
}
}
Then implement any services you need:
@Injectable({
providedIn: 'root'
})
export class BookService implements DataItemsService {
fetch(): Observable<DataItem[]> {
return of([{value: 'book1'}, {value: 'book2'}]);
}
}
@Injectable({
providedIn: 'root'
})
export class NamesService implements DataItemsService {
fetch(): Observable<DataItem[]> {
return of([{value: 'name1'}, {value: 'name2'}]);
}
}
The only left is to specify the desired service in providers list of the parent component.
Using BookService:
@Component({
selector: 'app-demo1',
template: `
<app-feature></app-feature>
`,
providers: [
{ provide: DataItemsService, useClass: BookService },
],
})
export class Demo1Component {}
Using NameService:
@Component({
selector: 'app-demo1',
template: `
<app-feature></app-feature>
`,
providers: [
{ provide: DataItemsService, useClass: NamesService },
],
})
export class Demo1Component {}
Upvotes: 0
Reputation: 8773
You can use @Input/Suscriber/localstorage in the component to get which method you want to call dynamic method. I assume you already have the name of dynamic method, you can call it like this:
public methodName: string = "Assign your method name dynamically to it"
ngOnInit(): void {
this.booksService[`${methodName}`]()
.subscribe((response) => (this.items = response));
}
Upvotes: 1