简体   繁体   中英

Angular 7 - Observable array of Observables arrays of an Object

I have the following problem, i have an array of articles at my article-service class, i need to display those articles in my main page by 3 articles by row, so i created an array of arrays of 3 articles by array. My main page needs to display each article and when clicked route to articles/article:id. My problem is that when i click the article, the route works well but the article doesn't display.

if i refresh the browser at localhost:4200/articles/1, it displays perfectly all the atributes of the article with id = 1, but when im at localhost:4200/blog and i click an article to go to localhost:4200/articles/1, nothing is displayed

Article class:

export class Article {
    id: string;
    title: string;
    briefInfo: string;
    topic: string;
    author: string;
    authorImg: string;
    relatedArticlesId: string[];
    mainImg: string;
    bodyHtml: string;
    date: string;

    constructor() {

    }
}

Article-Service class:

arrayGroupedBy3: Article[][] = [];

getArticlesGroupedBy3(): Observable<Article[][]> {
    if (this.articles.length > 3) {
      while (this.articles.length > 0) {
        this.articles.map( ( ): Article[] => {
          return this.articles.splice(0, 3);
        }).forEach( item => this.arrayGroupedBy3.push(item));
      }
    }
    return of(this.arrayGroupedBy3);
  }

getArticleById(id: string): Observable<Article> {
  return of(this.articles.find(item => item.id === id));
}

Article-list component class:

articlesOf3$: Observable<Article[][]>;
selectedId: string;

  constructor(private articleService: ArticleService, private router: ActivatedRoute ) {
  }
ngOnInit() {
  this.getArticles();
}

getArticles() {
   this.articlesOf3$ = this.router.paramMap.pipe(
     switchMap( params => {
       this.selectedId = params.get('id');
       return this.articleService.getArticlesGroupedBy3();
    }));
}

article-list.component.html class:

<section class="row content_articles">
  <article class="center_content">

    <ul *ngFor="let listOf3articlesMax of articlesOf3$ | async" 
      class="row content_list articles">
      <li *ngFor="let article of listOf3articlesMax" 
        [class.selected] = "article.id === selectedId"
        class="{{article.topic}}">
        <a [routerLink]="['/articles',article.id]">
          <figure class="row article_img">
            <img src="{{article.mainImg}}" alt="" title="">
          </figure>
          <div class="row content_information">
          <!--Tag-->
            <span class="content_tag">{{article.topic}}</span>
            <div class="row content_text">
              <h4>{{article.title}}:</h4>
              <p>{{article.briefInfo}}</p>
            </div>
          </div>
          <div class="row author_information">
            <figure>
              <img src="{{article.authorImg}}" alt="" title="" />
            </figure>
            <div class="author">
              <h5>by {{article.author}}</h5>
              <span class="date">{{article.date}}</span>
            </div>
          </div>
        </a>
      </li>
    </ul>
</article>
</section>

article.component class:

  article: Article;
  article$: Observable<Article>;

  constructor(
    private articleService: ArticleService,
    private route: ActivatedRoute,
    private location: Location,
    ) { }


  ngOnInit(): void {
    this.getArticleById();
  }

  getArticleById(): void {
    this.article$ = this.route.paramMap.pipe(
      switchMap((params: ParamMap) => this.articleService.getArticleById(params.get('id'))));

  }
  goBack(): void {
    this.location.back();
  }

and finally the article.component.html class:

<section *ngIf="article$" class="row content_blog_detail {{article$.topic}}">
<div class="row content_article">
        <!--Tag-->
        <span class="content_tag">{{article$.topic}}</span>
        <!--Titles-->
        <h1 class="row">{{article$.title}}</h1>
        <h2 class="row">{{article$.briefInfo}}</h2>

        <!--Return-->
        <a (click)="goBack()" class="btn_return">Back</a>
</div>
</section>

app-routing module:

const routes: Routes = [
  {path: 'blog', component: ArticleListComponent},
  {path: 'articles/:id', component: ArticleComponent}
];

Actually the list of 3 articles by row displays ok, but when an article is clicked to go to the route of that article id, none of the details of the article is displayed.

Your article$ property is an Observable. You need to subscribe to it before you can access the Article object's properties in your Article Component.

You should use Angular's async pipe to render out the Article:

<section *ngIf="article$ | async as article" class="row content_blog_detail {{article.topic}}">
<div class="row content_article">
        <!--Tag-->
        <span class="content_tag">{{article.topic}}</span>
        <!--Titles-->
        <h1 class="row">{{article.title}}</h1>
        <h2 class="row">{{article.briefInfo}}</h2>

        <!--Return-->
        <a (click)="goBack()" class="btn_return">Back</a>
</div>
</section>

StackBlitz demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM