0

I want to sort an array of posts by createdAt dates, now the posts are sorting by first the oldest one then the new one, but I want to be sorted the opposite way! already tried .sort((a, b) => b.createdAt - a.createdAt) but didn't work, I'm not sure if it's the way to implement it. The post data is stored in mongodb as shown in the picture below

Posts Model: enter image description here

Post.jsx Code:

export default function Posts({ posts = [] }) {

    const [filteredResults, setFilteredResults] = useState([]);
    const [searchInput, setSearchInput] = useState('');
    const [isLoading, setIsLoading] = useState(false);
  
    const filter = (e) => {
      const keyword = e.target.value;
  
        if (keyword !== '') {
            const filteredData = posts.filter((post) => {
                return Object.values(post)
                .join('')
                .toLowerCase()
                .includes(searchInput.toLowerCase())
            })
            setFilteredResults(filteredData)
            
        } else {
          setFilteredResults(posts)
        }
  
        setSearchInput(keyword);
    }
    console.log(filteredResults)

  return (
    <div className="posts">
      <div className="postsContainer">

      <div className="postsSearchContainer">
            <div className="postsSearch">
                  <div class="postsSearchIconContainer">
                      <SearchIcon class="w-5 h-5" />
                  </div>
                    <input type="text"
                    className="postsSearchInput"
                    placeholder="بحث"
                    name="postsSearchText"
                    id="postsSearchText"
                    onChange={filter}
                    />
              </div>
              {/* ENDS OF POSTSSEARCHCONTAINER */}
      </div>
      {/* ENDS OF POSTSSEARCH */}
    <div className="postsBoxContainer">
      <div className="postsBox">
      {isLoading ? (
          <Box sx={{ display: 'flex' }}>
            <CircularProgress />
          </Box>
      ) : (
        filteredResults.length > 0 ? (
          filteredResults.map((p) => (
            <Post post={p} />
          ))
          ) : (posts.map((p) => (
            <Post post={p} />
          ))
        )
        }
      </div>
      </div>
      {/* ENDS OF POSTSBOX */}

      </div>
      {/* ENDS OF POSTCONTAINER */}

    </div>
    //ENDS OF POSTS

  );
};

The Code I tried:

(
        filteredResults.length > 0 ? (
          filteredResults.map((p) => (
            <Post post={p} />
          )).sort((a, b) => b.createdAt - a.createdAt)
          ) : (posts.map((p) => (
            <Post post={p} />
          )).sort((a, b) => b.createdAt - a.createdAt))
        )
sultan.h
  • 331
  • 1
  • 4
  • 16
  • can you attach the sorting code that you tried ? – KcH Nov 16 '22 at 17:44
  • ( filteredResults.length > 0 ? ( filteredResults.map((p) => ( )).sort((a, b) => b.createdAt - a.createdAt) ) : (posts.map((p) => ( )).sort((a, b) => b.createdAt - a.createdAt)) ) – sultan.h Nov 16 '22 at 17:49
  • 2
    Does this answer your question? [How to sort an object array by date property?](https://stackoverflow.com/questions/10123953/how-to-sort-an-object-array-by-date-property) – Axekan Nov 16 '22 at 17:52
  • I doubt if it works .... you are returning component's from map and then trying to sort them – KcH Nov 16 '22 at 18:02
  • @KcH then what is the best way to implement it? – sultan.h Nov 16 '22 at 18:20
  • @sultan.h shared my thoughts as answer below if its helpful // – KcH Nov 16 '22 at 18:22

3 Answers3

0

convert your dates strings into timestamps (in case they are all ready a date object just use the getTime()

sort((a, b) => new Date(b.createdAt).getTime()  - new Date(a.createdAt).getTime() )
Amit Wagner
  • 3,134
  • 3
  • 19
  • 35
0

Solution

 filteredResults.length > 0 ? (
          filteredResults.map((p) => (
            <Post post={p} />
          )).sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))
          ) : (posts.map((p) => (
            <Post post={p} />
          )).sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)))
        )

//example
const data = [
    "2022-11-17T17:51:45.537+00:00",
    "2022-11-17T17:51:45.539+00:00",
    "2022-11-16T18:51:45.537+00:00",
    "2022-11-15T17:51:45.537+00:00",
    "2022-11-16T17:51:45.537+00:00"
    ]
    
console.log(data.sort((a, b) => new Date(b) - new Date(a)));
codinn.dev
  • 263
  • 1
  • 8
  • 1
    If this does answer the question, it would benefit from a brief explanation of how/why it solves the problem. – starball Nov 16 '22 at 18:16
0

I guess you may want to sort first then map over it because you are returning component's from map and then trying to sort them which is not intented to be if I'm not wrong here ...

As sort does sorting the array in place (mutates original array) you might want to have the copy and sort it.

for e.g. [... your_data].sort((a,b)=> ....).map(p => <Post post={p} />)

you can take the approaches of sorting time from the other answers suggested here ...

KcH
  • 3,302
  • 3
  • 21
  • 46