1

I'm using this code to translate each word with translateBack

<span *ngFor="let word of getWords(); index as i">
  <button (click)="speak(word)"
  [matTooltip]="translateBack(word) | async">{{word}}</button>
</span>

where translateBack is

translateBack(word: string) {
  const options = {q: word, source: 'ru-RU', target: 'en-GB'};
  return this._http.post(url + key, options).pipe(
    take(1),
    map((res: any) => res.data.translations[0].translatedText)
  )
}

but in my console it shows a never-ending log of http requests. How do just take one? (i tried take(1))

Oba Api
  • 231
  • 1
  • 3
  • 10
  • for every buttons in the for loop, you are making an http request it makes sense for the program to make a lot of http requests here. take(1) for an http request is not really useful since a Post/Get request (using the angular-http) returns only once and completes. – Jensen Jun 03 '21 at 08:55
  • 1
    When you call functions and methods from the template they get called on every "tick", too; I'd suggest making `translateBack` into a pipe itself. – jonrsharpe Jun 03 '21 at 08:56
  • @jonrsharpe is it really on every "tick"? I thought angular updates where things changed after every tick. – Jensen Jun 03 '21 at 08:58
  • 1
    @Jensen see e.g. https://stackoverflow.com/q/64499097/3001761 – jonrsharpe Jun 03 '21 at 08:59
  • Thanks for suggestion @jonrsharpe, does a pipe mean that you avoid rerendering for every tick? – Oba Api Jun 03 '21 at 09:15

1 Answers1

2

In Angular it's better use forkJoin that make a call in a loop:

Use a forkJoin to translate all the words at time

translateWord=forkJoin(this.getWords().map(word=>{
   const options = {q: word, source: 'ru-RU', target: 'en-GB'};
   //I suppose is this.url and this.key
   return this._http.post(this.url + this.key, options).pipe(map(
        (res:any)=>({word:word,translate:res.data.translations[0].translatedText})))
   }
   ))

And use

<span *ngFor="let word of translateWord|async; index as i">
  <button (click)="speak(word.word)"
  [matTooltip]="word.translate">{{word.word}}</button>
</span>
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Great answer, thanks, but I'm getting this typescript error: any Object is of type 'unknown'.ngtsc(2571) for word.word and word.translate – Oba Api Jun 03 '21 at 09:42
  • ::glups:: I suppose is the this.getWords().map( **x** =>{...} (is this.getWords().map( **word** =>{...} -just corrected in code- – Eliseo Jun 03 '21 at 11:03