elliot_m
elliot_m

Reputation: 15

sort a list of objects by date in angular

i want to sort by date the array of posts, but first i want to see if there are objects in posts, the list of posts is showed correctly in the html but in console.log it looks undefined. can you help me?

posts.component.ts

import { Component, OnInit } from '@angular/core';
import { Post } from '../post';
import { LoginService } from '../login.service';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { PostsService} from '../posts.service';
import { registerLocaleData } from '@angular/common';
import localeIt from '@angular/common/locales/it';

registerLocaleData(localeIt, 'it');

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

  constructor(private loginservice: LoginService,
              private location: Location,
              private postsservice: PostsService) {}
  posts: Post[];
  postDetail(id: number){}

  ngOnInit() {
    this.getPosts();
    console.log(this.posts);
  }

 getPosts(): void {

   this.postsservice.getPosts()
   .subscribe(posts=>this.posts=posts);

 }


}

post.component.html

<div>
<ul>
  <li *ngFor="let post of posts">
    <p>{{ post.title }}</p>
    <p>written by {{ post.author }}  {{ post.date | date:'medium':'':''}}
      <a class="details" routerLink="/detail/{{post.id}}">></a>
    </p>
    <br>
  </li>
</ul>
</div>

posts.service.ts

import { Injectable } from '@angular/core';
import { Post } from './post';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { HttpClient, HttpHeaders } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable()
export class PostsService {

  private postsUrl = 'api/posts';  // URL to web api
  posts = [];

  constructor(private http: HttpClient) { }

  /** GET posts from the server */
  getPosts (): Observable<Post[]> {
    return this.http.get<Post[]>(this.postsUrl)
  }

  getPost(id: number): Observable<Post> {
    const url = `${this.postsUrl}/${id}`;
    return this.http.get<Post>(url);
  }

  /** PUT: update the post on the server */
  updatePost (post: Post): Observable<any> {
    return this.http.put(this.postsUrl, post, httpOptions);
  }

  /** POST: add a new post to the server */
  addPost (post: Post): Observable<Post> {
    return this.http.post<Post>(this.postsUrl, post, httpOptions);
  }
  /** DELETE: delete the post from the server */
  deletePost (post: Post | number): Observable<Post> {
    const id = typeof post === 'number' ? post : post.id;
    const url = `${this.postsUrl}/${id}`;

    return this.http.delete<Post>(url, httpOptions);
  }
}

Upvotes: 1

Views: 827

Answers (1)

glendaviesnz
glendaviesnz

Reputation: 1899

If you want to check that there are posts you can use a filter. That way you don't need any logic for this when you subscribe to the observable eg.

getPosts (): Observable<Post[]> {
    return this.http.get<Post[]>(this.postsUrl)
           .pipe(filter(posts => posts && posts.length > 0));
}

Rather than sorting the posts in the subscribe of the component I would be inclined to keep the logic in the service and use a map for this, eg.

getPosts (): Observable<Post[]> {
    return this.http.get<Post[]>(this.postsUrl)
           .pipe(
                filter(posts => posts && posts.length > 0),
                map(posts => sortBy(posts, ['date'])
            );
}

In the above example I have just used the lodash sortBy syntax, but you can use what ever method you want in the map to return the sorted array. If you have a need elsewhere for unsorted posts you can either have a separate getSortedPosts method, or pass a parameter to getPosts(sortBy).

Upvotes: 1

Related Questions