Sequential and dependent queries with rxjs










1















I'm trying to make multiple sequential and dependent queries on a Firebase database.
This is how the database look like :



books : book1: title: 'Book 1', author: 'author1' 
authors: author1: name: 'Author 1'


I'd like to retrieve all the books, iterate through them, get the related author name, set the value in each book object and return an Observable array containing the book objects.



I tried this way :



getBooks(): Observable<Book> 
return this._af.database
.list('/books')
.flatMap(e => e)
.concatMap(e => this.getAuthor(e.author), (a, b) =>
a.author = b.lastName;
return a;
);



But this returns the first book only.










share|improve this question
























  • Use mergeMap() (alias flatMap())

    – Günter Zöchbauer
    Nov 23 '16 at 8:58











  • Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

    – untemps
    Nov 23 '16 at 10:02












  • Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

    – Günter Zöchbauer
    Nov 23 '16 at 10:03











  • @untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

    – martin
    Nov 23 '16 at 13:36











  • @martin That's sound promissing, thank you.

    – untemps
    Nov 23 '16 at 13:39















1















I'm trying to make multiple sequential and dependent queries on a Firebase database.
This is how the database look like :



books : book1: title: 'Book 1', author: 'author1' 
authors: author1: name: 'Author 1'


I'd like to retrieve all the books, iterate through them, get the related author name, set the value in each book object and return an Observable array containing the book objects.



I tried this way :



getBooks(): Observable<Book> 
return this._af.database
.list('/books')
.flatMap(e => e)
.concatMap(e => this.getAuthor(e.author), (a, b) =>
a.author = b.lastName;
return a;
);



But this returns the first book only.










share|improve this question
























  • Use mergeMap() (alias flatMap())

    – Günter Zöchbauer
    Nov 23 '16 at 8:58











  • Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

    – untemps
    Nov 23 '16 at 10:02












  • Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

    – Günter Zöchbauer
    Nov 23 '16 at 10:03











  • @untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

    – martin
    Nov 23 '16 at 13:36











  • @martin That's sound promissing, thank you.

    – untemps
    Nov 23 '16 at 13:39













1












1








1








I'm trying to make multiple sequential and dependent queries on a Firebase database.
This is how the database look like :



books : book1: title: 'Book 1', author: 'author1' 
authors: author1: name: 'Author 1'


I'd like to retrieve all the books, iterate through them, get the related author name, set the value in each book object and return an Observable array containing the book objects.



I tried this way :



getBooks(): Observable<Book> 
return this._af.database
.list('/books')
.flatMap(e => e)
.concatMap(e => this.getAuthor(e.author), (a, b) =>
a.author = b.lastName;
return a;
);



But this returns the first book only.










share|improve this question
















I'm trying to make multiple sequential and dependent queries on a Firebase database.
This is how the database look like :



books : book1: title: 'Book 1', author: 'author1' 
authors: author1: name: 'Author 1'


I'd like to retrieve all the books, iterate through them, get the related author name, set the value in each book object and return an Observable array containing the book objects.



I tried this way :



getBooks(): Observable<Book> 
return this._af.database
.list('/books')
.flatMap(e => e)
.concatMap(e => this.getAuthor(e.author), (a, b) =>
a.author = b.lastName;
return a;
);



But this returns the first book only.







angular rxjs angularfire2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 11:17









Paul Floyd

2,69811730




2,69811730










asked Nov 23 '16 at 8:55









untempsuntemps

477




477












  • Use mergeMap() (alias flatMap())

    – Günter Zöchbauer
    Nov 23 '16 at 8:58











  • Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

    – untemps
    Nov 23 '16 at 10:02












  • Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

    – Günter Zöchbauer
    Nov 23 '16 at 10:03











  • @untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

    – martin
    Nov 23 '16 at 13:36











  • @martin That's sound promissing, thank you.

    – untemps
    Nov 23 '16 at 13:39

















  • Use mergeMap() (alias flatMap())

    – Günter Zöchbauer
    Nov 23 '16 at 8:58











  • Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

    – untemps
    Nov 23 '16 at 10:02












  • Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

    – Günter Zöchbauer
    Nov 23 '16 at 10:03











  • @untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

    – martin
    Nov 23 '16 at 13:36











  • @martin That's sound promissing, thank you.

    – untemps
    Nov 23 '16 at 13:39
















Use mergeMap() (alias flatMap())

– Günter Zöchbauer
Nov 23 '16 at 8:58





Use mergeMap() (alias flatMap())

– Günter Zöchbauer
Nov 23 '16 at 8:58













Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

– untemps
Nov 23 '16 at 10:02






Can you be more specific? I tried to use flatMap(), concatMap(), mergeMap(), etc. but, apparently, I don't know how to use them.

– untemps
Nov 23 '16 at 10:02














Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

– Günter Zöchbauer
Nov 23 '16 at 10:03





Can you be more specific? ;-) Please edit the question and post the code that demonstrates what you try to accomplish, what you tried and where you failed.

– Günter Zöchbauer
Nov 23 '16 at 10:03













@untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

– martin
Nov 23 '16 at 13:36





@untemps One of these answers could help you stackoverflow.com/questions/40170157/… stackoverflow.com/questions/40346728/… stackoverflow.com/questions/40250882/…

– martin
Nov 23 '16 at 13:36













@martin That's sound promissing, thank you.

– untemps
Nov 23 '16 at 13:39





@martin That's sound promissing, thank you.

– untemps
Nov 23 '16 at 13:39












2 Answers
2






active

oldest

votes


















0














Given that list(/books) returns an array like [bookObj, bookObj] you would need to fetch the author information of each book, no need for concatMap unless order preservation of your input books is required for the output.



 getBooks(): Observable<Book> 
return this._af.database
.list('/books')
.flatMap(booksArr => Rx.Observable.from(booksArr))
.flatMap(
book => this.getAuthor(e.author),
(book,a) =>
a.author = book.lastName;
return a;

);






share|improve this answer

























  • Thanks but that actually doesn't work since books is an array with no flatMap method.

    – untemps
    Nov 24 '16 at 9:14











  • ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

    – Mark van Straten
    Nov 24 '16 at 10:58


















0














Being unable to achieve this using operators, I have created an Observable via create() method and perform the queries before returning a new array :



getBooks(): Observable<Book> 
return Observable.create(observer =>
const res: Book = ;
this._af.database
.list('/books').subscribe(books =>
books.map(book =>
this.getAuthor(book.author).subscribe(author =>
res.push(
new Book(book.$key, book.title, author.lastName, book.price, book.image)
);
if (res.length === books.length)
observer.next(res);

)
);
);
);



That's not what I expected but it works.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f40759838%2fsequential-and-dependent-queries-with-rxjs%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Given that list(/books) returns an array like [bookObj, bookObj] you would need to fetch the author information of each book, no need for concatMap unless order preservation of your input books is required for the output.



     getBooks(): Observable<Book> 
    return this._af.database
    .list('/books')
    .flatMap(booksArr => Rx.Observable.from(booksArr))
    .flatMap(
    book => this.getAuthor(e.author),
    (book,a) =>
    a.author = book.lastName;
    return a;

    );






    share|improve this answer

























    • Thanks but that actually doesn't work since books is an array with no flatMap method.

      – untemps
      Nov 24 '16 at 9:14











    • ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

      – Mark van Straten
      Nov 24 '16 at 10:58















    0














    Given that list(/books) returns an array like [bookObj, bookObj] you would need to fetch the author information of each book, no need for concatMap unless order preservation of your input books is required for the output.



     getBooks(): Observable<Book> 
    return this._af.database
    .list('/books')
    .flatMap(booksArr => Rx.Observable.from(booksArr))
    .flatMap(
    book => this.getAuthor(e.author),
    (book,a) =>
    a.author = book.lastName;
    return a;

    );






    share|improve this answer

























    • Thanks but that actually doesn't work since books is an array with no flatMap method.

      – untemps
      Nov 24 '16 at 9:14











    • ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

      – Mark van Straten
      Nov 24 '16 at 10:58













    0












    0








    0







    Given that list(/books) returns an array like [bookObj, bookObj] you would need to fetch the author information of each book, no need for concatMap unless order preservation of your input books is required for the output.



     getBooks(): Observable<Book> 
    return this._af.database
    .list('/books')
    .flatMap(booksArr => Rx.Observable.from(booksArr))
    .flatMap(
    book => this.getAuthor(e.author),
    (book,a) =>
    a.author = book.lastName;
    return a;

    );






    share|improve this answer















    Given that list(/books) returns an array like [bookObj, bookObj] you would need to fetch the author information of each book, no need for concatMap unless order preservation of your input books is required for the output.



     getBooks(): Observable<Book> 
    return this._af.database
    .list('/books')
    .flatMap(booksArr => Rx.Observable.from(booksArr))
    .flatMap(
    book => this.getAuthor(e.author),
    (book,a) =>
    a.author = book.lastName;
    return a;

    );







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 24 '16 at 10:59

























    answered Nov 24 '16 at 7:39









    Mark van StratenMark van Straten

    6,63222450




    6,63222450












    • Thanks but that actually doesn't work since books is an array with no flatMap method.

      – untemps
      Nov 24 '16 at 9:14











    • ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

      – Mark van Straten
      Nov 24 '16 at 10:58

















    • Thanks but that actually doesn't work since books is an array with no flatMap method.

      – untemps
      Nov 24 '16 at 9:14











    • ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

      – Mark van Straten
      Nov 24 '16 at 10:58
















    Thanks but that actually doesn't work since books is an array with no flatMap method.

    – untemps
    Nov 24 '16 at 9:14





    Thanks but that actually doesn't work since books is an array with no flatMap method.

    – untemps
    Nov 24 '16 at 9:14













    ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

    – Mark van Straten
    Nov 24 '16 at 10:58





    ahh, if list('/books') returns a vanilla array then you need to convert it to an observable using flatMap(booksArr => Rx.Observable.from(booksArr)) so all the books are emitted as events on the observable stream.

    – Mark van Straten
    Nov 24 '16 at 10:58













    0














    Being unable to achieve this using operators, I have created an Observable via create() method and perform the queries before returning a new array :



    getBooks(): Observable<Book> 
    return Observable.create(observer =>
    const res: Book = ;
    this._af.database
    .list('/books').subscribe(books =>
    books.map(book =>
    this.getAuthor(book.author).subscribe(author =>
    res.push(
    new Book(book.$key, book.title, author.lastName, book.price, book.image)
    );
    if (res.length === books.length)
    observer.next(res);

    )
    );
    );
    );



    That's not what I expected but it works.






    share|improve this answer





























      0














      Being unable to achieve this using operators, I have created an Observable via create() method and perform the queries before returning a new array :



      getBooks(): Observable<Book> 
      return Observable.create(observer =>
      const res: Book = ;
      this._af.database
      .list('/books').subscribe(books =>
      books.map(book =>
      this.getAuthor(book.author).subscribe(author =>
      res.push(
      new Book(book.$key, book.title, author.lastName, book.price, book.image)
      );
      if (res.length === books.length)
      observer.next(res);

      )
      );
      );
      );



      That's not what I expected but it works.






      share|improve this answer



























        0












        0








        0







        Being unable to achieve this using operators, I have created an Observable via create() method and perform the queries before returning a new array :



        getBooks(): Observable<Book> 
        return Observable.create(observer =>
        const res: Book = ;
        this._af.database
        .list('/books').subscribe(books =>
        books.map(book =>
        this.getAuthor(book.author).subscribe(author =>
        res.push(
        new Book(book.$key, book.title, author.lastName, book.price, book.image)
        );
        if (res.length === books.length)
        observer.next(res);

        )
        );
        );
        );



        That's not what I expected but it works.






        share|improve this answer















        Being unable to achieve this using operators, I have created an Observable via create() method and perform the queries before returning a new array :



        getBooks(): Observable<Book> 
        return Observable.create(observer =>
        const res: Book = ;
        this._af.database
        .list('/books').subscribe(books =>
        books.map(book =>
        this.getAuthor(book.author).subscribe(author =>
        res.push(
        new Book(book.$key, book.title, author.lastName, book.price, book.image)
        );
        if (res.length === books.length)
        observer.next(res);

        )
        );
        );
        );



        That's not what I expected but it works.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 24 '16 at 14:11

























        answered Nov 24 '16 at 14:03









        untempsuntemps

        477




        477



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f40759838%2fsequential-and-dependent-queries-with-rxjs%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto