Как установить значение для провайдера, полученного из API-интерфейса в Angular - PullRequest
0 голосов
/ 17 февраля 2020

как мне установить здесь значение из API?

enter image description here

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

В идеале вы бы достигли этого с помощью асинхронной c фабрики в ваших провайдерах. К сожалению, какое-то время это был открытый выпуск .

Обходным путем может быть создание службы-оболочки, которая сначала загружает ключ API, а затем воспроизводит загруженную службу из темы.

@Injectable({ providedIn: 'root'}) 
export class ServiceWrapper {

  private service$: Subject<Service>;

  getService(): Observable<Service> {
    if (this.service$) {
      return this.service$.pipe(
        take(1)
      );
    }

    this.service$ = new ReplaySubject<Service>(1);

    this.http.get(apiKeyUrl).subscribe(apiKey => {
      this.service$.next(new Service(apiKey));
    });

    return this.service$.pipe(
      take(1)
    );
  }
}

Затем вы добавляете эту службу-оболочку в компоненты (или что бы она ни потребляла):

export class MyComponent {
  constructor(private service: ServiceWrapper) {}

  ngOnInit(): void {
    this.service.getService().pipe(
      switchMap(service => service.method())
    ).subscribe(result => {
      // do something
    });
  }
}

В результате вы получите множество вызовов switchMap, так что Это не идеальный вариант, но это обходной путь.

Если бы у вас были какие-либо другие зависимости, которые вам нужно было добавить в службу, вы бы также добавили их в службу оболочки.

Рабочая демонстрация: https://stackblitz.com/edit/angular-wlbyqp

0 голосов
/ 17 февраля 2020

Вы можете использовать фабрику

В модуле инициализировать сервис и вызвать API


export function setupFactory(myService:MyService) {
  return () => myService.load();
}

@NgModule({
  declarations: [
    AppComponent,
    TestComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [
    { provide: APP_INITIALIZER,  useFactory: setupFactory, deps: [MyService], multi: true }, ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Затем вы можете вызвать функцию, чтобы получить ключ API

@Injectable({ providedIn: 'root'}) 
export class MyService {

  private _apiKey = '';

  public apiKey(): string {
    return this._apiKey;
  }

  public async load() {
    // Simulate calling the API
    this._apiKey = await new Promise((r) => {
      r('you api key')
    })
  }
}

let apiFactory = (MyService: MyService) => {
  return MyService.apiKey();
}


providers: [{ provide: 'googleTagManagerId',  useFactory: apiFactory, deps: [MyService] }]

...