I am not sure if this is doable, but can a service be called on its methods from inside an export function that's residing in a non-Angular component (e.g., just a Typescript file)?
Example: supposed we have this container-managed service that's easily injectable inside Angular components.
import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { Contact } from "@comp-store/data-model";
const URL = 'http://localhost:3333/api/contacts';
@Injectable({
providedIn: 'root'
})
export class ContactsService {
constructor(private http: HttpClient) {}
sayHello(): string {
return "hello there!";
}
all(): Observable<Contact[]> {
return this.http.get<Contact[]>(URL);
}
}
Now, suppose I have a mere Typescript file called utils.ts
with this content only:
export const callTheService = () => {
console.log('==> about to call the service...');
// here, I need to get a handle on the `ContactsService` and if doable, then:
// - easy: call the sayHello() method to say hello, then
// - no easy: call the all() method to receive the returned contacts
}
With the setup above, I need to be able to issue a callTheService()
call and have it deliver, is this possible?
Note: I know I can pass the service as a parameter but this is not the objective. The objective is to have the method summon the service from its inside.
=================
UPDATE: The more I think about it, the more I think it isn't doable. For example, I would have to write code like this inside an Angular component if I need to perform manual DI, something like:
function contactServiceProvider(http: HttpClient): ContactsService {
return new ContactsService(http);
}
export const CONTACT_SERVICE =
new InjectionToken<ContactsService>('CONTACT_SERVICE');
@Component({
selector: 'comp-store-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
providers: [
{
provide: CONTACT_SERVICE,
useFactory: contactServiceProvider,
deps: [HttpClient]
}
]
})
export class HeaderComponent {
constructor(@Inject(CONTACT_SERVICE) private service: ContactsService) {}
// ...
So, having code like this inside plain Typescript files is simply not possible.
CodePudding user response:
Angular 14 has inject()
- there's some good examples from netbasal - you need to initially invoke the functions that use inject
from the constructor (or property initializer) of an Angular component/service
import { inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
export function getRouteParam(key: string) {
return inject(ActivatedRoute).snapshot.params[key];
}
@Component({
selector: 'app-todo-page',
templateUrl: './todo-page.component.html',
})
export class TodoPageComponent {
id = getRouteParam('id');
ngOnInit() {
console.log(this.id)
}
}
CodePudding user response:
Prior to Angular 14, no.
I assume somewhere further up the call stack you'll be in Angular code so could inject the service there, and pass the service as a parameter to your util function:
export const callTheService = (contactsService: ContactsService) => {
contactsService.sayHello();
// etc
}