2

I have just started using the ng2 translate in my Ionic 2 (Angular 2) project. I Have found that when I need to get a few strings all at once, the code becomes nested and a lot harder to read. I am sort of wondering why something like this (that just emits a single value) need to use an observable, but perhaps there is a good reason. Anyway...

So for example, say I had 4 strings to read at various points in a method

let result1: string;
let result2: string;
let result3: string;
let result4: string;

this.translate.get("key1").subscribe(value1 => {
    result1 = value1;
    this.translate.get("key2").subscribe(value2 => {
        result2 = value2;

        // do some other stuff, which may have another observable returned so yet another level of nesting)

        this.translate.get("key3").subscribe(value3 => {
            result3 = value3;

            // do some other stuff

            this.translate.get("key4").subscribe(value4 => {
                result4 = value4;
            }
        }
        ...

Now imagine there is more than 4 string. Also when there is other code inbetween this (eg I May also call the Ionic storage which also returns an Observable), the code is getting very nested - and this is with no error handing.

So, the question is: is there a "flatter" way to do this? IS there any chaining (even if similar to a Promise "the chaining), perhaps including error handling (even if there was some kind of top level catch block)

I have seen other example of chaining, but they seem to do more with operators rather than lot of observables like the above.

cartant
  • 57,105
  • 17
  • 163
  • 197
peterc
  • 6,921
  • 9
  • 65
  • 131

2 Answers2

3

You don't have to chain them; you can use combineLatest to combine the observables:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/combineLatest';

Observable.combineLatest(
    this.translate.get("key1"),
    this.translate.get("key2"),
    this.translate.get("key3"),
    this.translate.get("key4")
)
.subscribe(([result1, result2, result3, result4]) => {
    console.log(result1);
    console.log(result2);
    console.log(result3);
    console.log(result4);
});
cartant
  • 57,105
  • 17
  • 163
  • 197
  • The above works great, but I am having problems trapping errors. Have opened this in a new [post](http://stackoverflow.com/questions/41755718/how-to-trap-errors-from-chained-rxjs-observables-when-using-combinelatest). – peterc Jan 20 '17 at 03:43
0

If you know all of your key values up front, you can use the translate.get() overload which takes a string array...

thus:

this.translate.get(['key1','key2','key3','key4'])
    .subscribe(keys => {
        console.log(keys.key1);
        console.log(keys.key2);
        console.log(keys.key3);
        console.log(keys.key4);
});
GrantDG
  • 401
  • 1
  • 7
  • 14