Sorting an object array by date is causing a problem

UPDATE: Finally cracked the code on this issue. I initially assumed that Date was interpreting the date ("29-04-2020") as DD-MM-YYYY, when it should actually be MM-DD-YYYY.
For instance, here's an object array I'm working with:

let todos: object[] = [
      {
        'id': 1,
        'title': 'Test',
        'description': 'Just a new task',
        'priority': 1,
        'status': 'during',
        'date': new Date('29-05-2020')
      },
      {
        'id': 2,
        'title': 'test23',
        'description': 'Just a new task23',
        'priority': 3,
        'status': 'done',
        'date': new Date('29-05-2020')
      },
      {
        'id': 3,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 2,
        'status': 'in process',
        'date': new Date('29-05-2020')
      },
      {
        'id': 4,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 1,
        'status': 'during',
        'date': new Date('29-05-2020')
      },
      {
        'id': 5,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 2,
        'status': 'done',
        'date': null
      },
      {
        'id': 6,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 1,
        'status': 'in process',
        'date': new Date('29-05-2020')
      },
]

My goal is to sort these objects by date while excluding keys with a null value (hence the use of the if operator). To achieve this, I've created a function:

function sortByDate() {
    todos.sort((a, b) => {
        console.log(a, b)
        if (a['date'] == null) {
            return 1;
        }
        if (b['date'] == null) {
            return -1;
        }
        return a['date'].getTime() - b['date'].getTime()
    })
    return todos
}

However, upon sorting, I noticed that where 'date' property existed but wasn't null, instead of correct date values, I received "Invalid date" entries in the 'date' key. Now, I'm stuck and unsure how to rectify this.

Answer №1

I discovered a couple of issues in your code:

  1. The object keys are in string format instead of being identifiers. Check out this resource for more information.
  2. The date string is reversed. Make sure to create the date from a string following the guidelines provided in the documentation.

To resolve this, you need to utilize filter to eliminate invalid dates and then proceed with calling the sort method.

If you wish to sort the array by Date in descending order, use the following code snippet:

const todos_filtered_sorted_desc = todos_filtered.sort((a, b) => b.date - a.date);

Alternatively, for ascending order, use the code below:

const todos_filtered_sorted_asc = todos_filtered.sort((a, b) => a.date - b.date);

Here is the revised and corrected code with different dates:

const todos = [
      {
        id: 1,
        title: 'Test',
        description: 'Just a new task',
        priority: 1,
        status: 'during',
        date: new Date('2020-05-29')
      },
      {
        id: 2,
        title: 'test23',
        description: 'Just a new task23',
        priority: 3,
        status: 'done',
        date: new Date('2019-05-29')
      },
      {
        id: 3,
        title: 'test3',
        description: 'Just a new task3',
        priority: 2,
        status: 'in process',
        date: new Date('2021-05-29')
      },
      {
        id: 4,
        title: 'test3',
        description: 'Just a new task3',
        priority: 1,
        status: 'during',
        date: new Date('2008-05-29')
      },
      {
        id: 5,
        title: 'test3',
        description: 'Just a new task3',
        priority: 2,
        status: 'done',
        date: null
      },
      {
        id: 6,
        title: 'test3',
        description: 'Just a new task3',
        priority: 1,
        status: 'in process',
        date: new Date('2000-05-29')
      },
];

console.log(`TODOS[${todos.length}]: ${JSON.stringify(todos)}`);

const todos_filtered = todos.filter(todo => todo !== null && todo !== undefined && todo.date !== null && todo.date !== undefined && todo.date instanceof Date);

console.log(`TODOS FILTERED[${todos_filtered.length}]: ${JSON.stringify(todos_filtered)}`);

const todos_filtered_sorted = todos_filtered.sort((a, b) => b.date - a.date);

console.log(`TODOS FILTERED SORTED[${todos_filtered_sorted.length}]: ${JSON.stringify(todos_filtered_sorted)}`);

You can combine all functions into a single operation like this:

const todos_filtered_sorted = todos
                               .filter(todo => todo !== null && todo !== undefined
                                 && todo.date !== null && todo.date !== undefined
                                 && todo.date instanceof Date)
                               .sort((a, b) => b.date - a.date);

I hope this solution helps! :)

Answer №2

Date format should follow yyyy-MM-dd

Check out the code snippet below

const todoList = [
      {
        'id': 1,
        'title': 'Test',
        'description': 'Just a new task',
        'priority': 1,
        'status': 'during',
        'date': new Date('2020-05-29')
      },
      {
        'id': 2,
        'title': 'test23',
        'description': 'Just a new task23',
        'priority': 3,
        'status': 'done',
        'date': new Date('2020-05-29')
      },
      {
        'id': 3,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 2,
        'status': 'in process',
        'date': new Date('2020-05-29')
      },
      {
        'id': 4,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 1,
        'status': 'during',
        'date': new Date('2020-05-29')
      },
      {
        'id': 5,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 2,
        'status': 'done',
        'date': null
      },
      {
        'id': 6,
        'title': 'test3',
        'description': 'Just a new task3',
        'priority': 1,
        'status': 'in process',
        'date': new Date('2020-04-29')
      },
];

function sortTasksByDate(todos) {
    todos = todos.filter(obj => obj.date !== null).sort((a, b) => {
        if(a.date == b.date) return 0;
        
        if (a.date < b.date)
            return -1;
        if (a.date > b.date)
            return 1;
        return 0;
    });
    console.log(todos);
    return todos
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring Vue 3: Crafting a custom plugin using the composition API and enhancing it with Typescript type augmentation

Encountering an issue with displaying plugins properly within <script> and <template> tags on WebStorm. Firstly, let's take a look at my files and configuration: tsconfig.config.json { "extends": "@vue/tsconfig/tsconfig. ...

Sort by label using the pipe operator in RxJS with Angular

I have a situation where I am using an observable in my HTML code with the async pipe. I want to sort the observable by the 'label' property, but I'm not sure how to correctly implement this sorting logic within the pipe. The labels can be e ...

What is the process of extending a class in TypeScript?

I have a few services that contain the same code: constructor (private http: Http) { //use XHR object let _build = (<any> http)._backend._browserXHR.build; (<any> http)._backend._browserXHR.build = () => { let _xhr = _ ...

Converting a string value into an object in Javascript using a command that functions similarly to eval in Python

When working with Python, the stringValue variable is often assigned as a string: stringValue = '{"DATA":{"VERSION":1.1, "STATE":True, "STATUS":"ONLINE"}}' To convert this string into a Python di ...

The iteration variable concludes with a value that is one higher than anticipated

When I run a basic loop in VBA within Excel that fills an array with values, something caught my attention. The counter begins at 0 but ends up at 7 instead of 6. This discrepancy becomes apparent when observing the Locals window and stepping through the c ...

Struggling with setting up the onChange function in a Next.js application

After successfully writing and testing the code here, I encountered an error preventing me from building it. Please review the code for any issues. I am attempting to set onChange to handle user input in a text field. Currently using onChange={onChange}, ...

Transforming a detailed JSON structure into a more simplified format with Angular 2

As a newcomer to Angular 2, I find myself encountering a hurdle in filtering unnecessary data from a JSON object that is retrieved from a REST API. Below is an example of the JSON data I am working with: { "refDataId":{ "rdk":1, "refDataTy ...

Creating Swagger documentation for dynamic request and response is a process that involves documenting the various

Our API application operates dynamically using SQL-defined metadata to generate reports based on the requests it receives. When a JSON request is passed in like the examples below: { "Field1": "Value1" "GroupBy": [&qu ...

Step-by-step guide on incorporating an external library into Microsoft's Power BI developer tools and exporting it in PBIVIZ format

I'm attempting to create a unique visualization in PowerBI using pykcharts.js, but I'm running into issues importing my pykcharts.js file into the developer tool's console. I've tried including a CDN path like this: /// <reference p ...

There is a JSON issue present, with half of the variables being undefined

Having an issue with my JSON as it throws me an undefined error. What's puzzling is that it recognizes my first variable without any problem. Below are the codes for better understanding: JSON {"Comics":[ {"comic" : { "src":"Pictures/Comic ...

Having trouble showing the fa-folders icon in Vuetify?

Utilizing both Vuetify and font-awesome icons has been a successful combination for my project. However, I am facing an issue where the 'fa-folders' icon is not displaying as expected: In the .ts file: import { library } from '@fortawesome/ ...

Navigate array in vue-chart.js

I've been utilizing Vue-chartjs with Laravel 5.7 for my project. The goal: I aim to pass an array to Vue so that I can dynamically generate a chart by looping through specific values. My approach so far: Here's the array I'm working with ...

Categories for the Promise.all() function

I'm feeling lost trying to understand the differences between the request tuple return type and Promise.all(). This is driving me crazy. Any suggestions? const createPromises = async (utteranceObject: Array<string[]>): Promise<Array<[s ...

What is the best way to test the validity of a form while also verifying email availability?

I am currently working on implementing async validation in reactive forms. My goal is to disable the submit button whenever a new input is provided. However, I am facing an issue where if duplicate emails are entered, the form remains valid for a brief per ...

Quickly sorting with just a single recursive invocation

We are all familiar with the traditional way of implementing quicksort using two or more recursive calls. A few days ago, our teacher mentioned that it could be possible to achieve the same sorting efficiency with just one recursive call. Personally, I am ...

Is it possible in core Node/Express to utilize a JSON file as a RESTful resource?

I have a JSON file with an array of 100 objects, each representing a person. I want to be able to retrieve ten person objects at a time from this JSON resource. Is there a way to implement a request in Node/Express where I can get back ten objects based on ...

Encountering a surprise token < while processing JSON with ASP.NET MVC alongside Angular

I encountered an issue when attempting to return the Index page. The data is successfully sent from the client to the server, but upon trying to display the Index page, an error occurs. Could someone review my code and identify where the mistake lies? acc ...

Creating Dynamic Forms in React with Typescript: A Step-by-Step Guide to Adding Form Elements with an onClick Event Handler

I am looking to create a dynamic generation of TextFields and then store their values in an array within the state. Here are my imports: import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button&apos ...

Dramatist - shutting down an angular pop-up dialog

I am currently utilizing the Playwright tool to carry out testing on an angular application. One particular scenario involves a modal that is displayed by default when a page is loaded. Despite my best efforts, I have been unable to successfully close this ...

Show content based on dynamically selected dropdown in Angular

I am facing an issue with a dynamic select element in Angular. I am struggling to display the selected values on the view because I cannot seem to create a click event on the dropdown options or access the selected option via a click event on the <selec ...