0

I have the following component:

import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params }   from '@angular/router';
import 'rxjs/add/operator/switchMap';

import { ArticleStore } from '../../state/ArticleStore';
import { Article } from '../../models/article';

@Component({
  selector: 'app-article-detail',
  templateUrl: './article-detail.component.html',
  styleUrls: ['./article-detail.component.css']
})
export class ArticleDetailComponent implements OnInit {

  private article: Article;

  constructor( private route: ActivatedRoute, private articleStore: ArticleStore ) { }

  ngOnInit(): void {
    this.route
        .queryParamMap
        .map((paramMap => paramMap.get('id') || 'None'))
        .switchMap((id: string) => this.articleStore.getArticle(id))
        .subscribe((article: Article) => {
            this.article = new Article(article);
            console.log(this.article) // <--returns full-filled object
        });

        console.log(this.article) // <-- undefined object
    }
}

Inside the subscribe function, I get the proper object (this.article) and is what I expect. If I move down to after the this.route, it doesn't work. Should be straight forward to get the value assigned.

The whole project is here => https://github.com/flamusdiu/micro-blog

Edit

Kinda similar to How do I return the response from an Observable/http/async call in angular2?

I understand the async nature of the calls (actually more calls now-a-days are async).

When you nav to article/:id, it fires off the getArticle(id) function from the ArticleStore.ts

public getArticle (id: string) {
    return this.pouchdbService.getArticle(id)
        .then((res) => {return res.docs[0] });
}

This runs just fine. It pulls from my service:

public getArticle(id: string): Promise<any> {
   return this._pouchDb.find({
      selector: {_id: id }
  });
}
flamusdiu
  • 1,722
  • 2
  • 14
  • 31
  • 1
    Also see http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call . It's not even null. It's undefined. `null !== undefined`. *Should be straight forward to get the value assigned* - no, it shouldn't. – Estus Flask Apr 16 '17 at 17:40
  • Oops, @estus your right. – flamusdiu Apr 16 '17 at 17:51
  • @estus that stackoverflow is similar. But I've tried everything that I've seen to work it out. I am guessing the whole function change completes without waiting for the returned article? – flamusdiu Apr 16 '17 at 17:59
  • Yes, your assumption is right. This is what http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call is about. With promises you could use async/await to 'wait' for the result, but RxJS observables don't work this way - `subscribe` callback may be called multiple times. – Estus Flask Apr 16 '17 at 18:04
  • @estus In my case, would be better to directly use the Promises provided by PouchDB instead of working with the RxJS observables? Though, I'll still need them for the search stuff later on. – flamusdiu Apr 16 '17 at 18:52
  • Nope. In your case you're using route query observable, so it may fire multiple times, which a promise cannot do. – Estus Flask Apr 16 '17 at 19:00

1 Answers1

0

In your application routes you should have something like:

{ path: '/articles/:id', component: ArticleDetailComponent},

Then your router will be able to act on the provided article route.

Also consider using a Resolver for getting data for the component before it is initialized. good luck with the blog :D

Andrei Voicu
  • 740
  • 1
  • 6
  • 13
  • Yeah, I am using { path: 'article/:id', component: ArticleDetailComponent }. It and getting there using from the article list view. I get to the view but can't resolve the problem. – flamusdiu Apr 16 '17 at 17:57
  • 1
    Add the resolver. Does fix my current issue though. ;) Check github above though if you want – flamusdiu Apr 16 '17 at 19:56
  • you were on the right track. i fixed it with the Resolver. Probably another way to fix it, however. – flamusdiu Apr 18 '17 at 18:25