javascriptangularhtmltypescripttimeago

dates are displaying in weird way angular 6


I have app in angular user can enter a comment , the comment display automaticaly and diplays a date it was added, the weird part is as following

  1. When a user enter a coment here is what is displayed (check time)

enter image description here

The first commet is from yesterday, the second coment is new one u can see after submiting dispaly a date an hour ago instead of just now? .

  1. When user refresh the browser here is what is displayed check the top comment time? enter image description here

What I want is the old comment should be on top and the new comment at the bottom and new comment should have time just now imeaditely not after refresh

Here is my solution , Note am momet js for date formating

function to add and get comments in ts

// get all comments
    this.activeRouter.params.subscribe((params) => {
        const id = params['id'];
        this.userService.getComments(id)
        .pipe(
          map(data => data.sort((a, b) => new Date(b.localTime).getTime() - new Date(a.localTime).getTime()))
        )
        .subscribe(data => this.comments = data);
     });
  }

// add comments to server
  addComments(task_id) {
    const formData = this.addForm.value;
    formData.task_id = task_id;
    this.userService.addComments(formData)
    .subscribe(data => {
      this.comments.push(this.addForm.value);
      this.addForm.reset();
    });
  // grab localtime
    const date = new Date();
    const d = date.getUTCDate();
    const day = (d < 10) ? '0' + d : d;
    const m = date.getUTCMonth() + 1;
    const month = (m < 10) ? '0' + m : m;
    const year = date.getUTCFullYear();
    const h = date.getUTCHours();
    const hour = (h < 10) ? '0' + h : h;
    const mi = date.getUTCMinutes();
    const minute = (mi < 10) ? '0' + mi : mi;
    const sc = date.getUTCSeconds();
    const second = (sc < 10) ? '0' + sc : sc;
    const loctime = `${year}-${month}-${day}T${hour}`;

    this. addForm.get('localTime').setValue(loctime);

  }

here is service

  // add comments
  addComments(comments: Comment) {
    comments.localTime = new Date();
    return this.http.post(this.commentsUrl, comments);
  }

  // get comments
  getComments(id: number): Observable<any> {
    return this.http.get(this.commentsUrl).pipe(
      map(this.extractData),
      catchError(this.handleError));
  }

json file how it looks

  "comment": [
    {
      "id": 1,
      "localTime": "2018-10-29T23:12:57.129Z",
      "description": "Putin is Dope\n"
    },
    {
      "id": 2,
      "localTime": "2018-10-29T23:13:25.743Z",
      "description": "Obama is cool \n"
    },
  {
      "id": 2,
      "localTime": "2018-10-29T23:13:25.743Z",
      "description": "No No do U know JOHN POMBE MAGUFULI? the president of Tanzania oooh oooh man he is savage , they call him Buldoser, Moderator please change the title "Who is the weakest president of all time?" => OBAMA  \n"
    }

  ]
}

Here is HTML

 <span class="days">{{comment.localTime | amTimeAgo}}</span>

Note: to get those time ago , horu ago etc I use pipe : https://www.npmjs.com/package/time-ago-pipe

what am I doing wrong in my codes???? thanks


Solution

  • That's because values, which you send to server and use immediately, are different. Notice, that directly you use loctime variable, which holds a value after some transformations, but you send to server just a new Date(). Here I logged these 2 values, pay attention on the difference:

    const date = new Date();
    const d = date.getUTCDate();
    const day = (d < 10) ? '0' + d : d;
    const m = date.getUTCMonth() + 1;
    const month = (m < 10) ? '0' + m : m;
    const year = date.getUTCFullYear();
    const h = date.getUTCHours();
    const hour = (h < 10) ? '0' + h : h;
    const mi = date.getUTCMinutes();
    const minute = (mi < 10) ? '0' + mi : mi;
    const sc = date.getUTCSeconds();
    const second = (sc < 10) ? '0' + sc : sc;
    const loctime = `${year}-${month}-${day}T${hour}`;
    
    console.log('date:', date);
    console.log('loctime:', loctime);
    console.log('typeof date:', typeof date);
    console.log('typeof loctime:', typeof loctime);

    As mentioned in docs, this pipe works with a regular Date, which you can get with new Date() command, and finally you can simply do this:

    this.addForm.get('localTime').setValue(new Date());
    

    or

    this.addForm.get('localTime').setValue(date);
    

    because you already stored this value to the date variable.

    Regarding the order:

    The order, when you get comments from server, and when you just add new comment without getting the list from server a different, because you use a sorting pipe only when get the list of comments from server. I mean this part:

    this.userService.getComments(id)
      .pipe(
        map(data => data.sort((a, b) => new Date(b.localTime).getTime() - new Date(a.localTime).getTime()))
      )
    

    To fix that, you can sort comments, after publishing them to server as well, but I believe that the simplest way is just to use .unshift() instead of .push(), like this:

    this.userService.addComments(formData)
      .subscribe(data => {
        this.comments.unshift(this.addForm.value);
        this.addForm.reset();
      });
    

    But this should work only if you haven't any additional transformations of this data before rendering, for example, pipes in HTML.