0

I have a problem with constructing filter data pipe. I would like to pass data with removed duplicates from my object.

This is my ngFor:

<ng-container *ngFor="let message of messages | filterDates">

I would like to pass my messages array through this pipe, to remove duplicate dates from each object. Each object in my array has

'timestamp': 1590064423327

some of objects has the same timestamp, and some of them not. I would like to set timestamp to null in those objects, if previous object from array has the same timestamp value. If previous has different timestamp value, I would like to pass timestamp as it is in current object.

To better understand, the example is: I'm receiving messages from my API with timestamps. I would like to show date for only first message, because next messages are from the same day, so there is no need to show date for those messages. If next messages are not from the same day, I would like to show only for the first message date value from next timestamp. It is for grouping messages by date.

I have prepared pipe for this, but unfortunately, I'm not sure what to do in this pipe to achieve this specific goal. I'm pretty sure, I should use Lodash, but I don't exactly know, which operator should I use. Thank you in advance for any help.

This is the problem I have from @Yogesh Developer answer:

enter image description here

I think problem here is, it's pushing to array element with null, then it compares next item with null timestamp. I forgot to mention, that I have to compare timestamps in formatted date way, because timestamps are with seconds so they will always be different. This is how I compare formatted dates with momentjs:

if (index > 0 && (moment(message.timestamp).format('DD/MM/YYYY') == moment(messages[index - 1].timestamp).format('DD/MM/YYYY'))) {
        message.timestamp = null
      }
      finalMessages.push(message)
3
  • 2
    You could simply traverse through your array with a simple for-each loop, save the last timestamp and compare that to the current timestamp. Create a new object for each entry whenever timestamp is omitted and push these to a new array. Commented May 25, 2020 at 15:47
  • What have you tried in the pipe ? Commented May 25, 2020 at 15:47
  • I have tried uniqBy from lodash, but this only groups me my objects by timestamps, and removed all objects where there are the same timestamps Commented May 25, 2020 at 16:16

3 Answers 3

1

Should works fine

let finalMessages = [];
let prevTimestamp = null;
messages.forEach((message, index) => {
  if (moment(message.timestamp).isSame(moment(prevTimestamp), 'days')) {
    message.timestamp = null
  } else {
    prevTimestamp = message.timestamp
  }
  finalMessages.push(message)
})
Sign up to request clarification or add additional context in comments.

Comments

0

You can do something like this in your filterDate pipe:

let finalMessages = []
messages.forEach((message, index) => {
  if (index > 0 && (message.timestamp == messages[index - 1])) {
    message.timestamp = null
  }
  finalMessages.push(message)
})

3 Comments

This works almost just as I want and I have tried that recently, but this only applies to messages with range index - 1. I have to apply this logic to all my objects at once, because once I pass null to specific object, it will check if it's the same in next iteration and it is not the same now because previous object in array has null value of timestamp.
If previous object has null timestamp then this means this message is not a part of previous group & new group starts from here. What's the problem in it?
I have updated the question with some more information
0

the simple solution is to create an array of displayMessages in your javascript, then use displayMessages in your NgFor loop.

let displayMessages = [];
let timeStampHash = {};
messages.forEach(message) => {
  if (!timeStampHash[message.timestamp]) {
    timeStampHash[message.timestamp] = true;
    displayMessages.push(message);
  }
})
this.displayMessages = displayMessages;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.