I'm using Gatsbyjs to query posts from 2 sources. Objects aren't uniform. I want posts sorted in descending order by date. The key used for sorting is nested at different levels depending on the object source. So I'm using Lodash to grab the deepest nested key and bring it a level higher. Then I sort the array.
https://jsbin.com/jetilahuxu/edit?js,console
In Javascript file:
const _ = require('lodash');
const posts=[
{node: {excerpt: "Lorem1", fields: {id: 13}, frontmatter: {description: "lorem", date: "2020-11-25T20:17:10+0100", title: "Lorem1"}}},
{node: {excerpt: "Lorem3", fields: {id: 12}, frontmatter: {description: "lorem", date: "2020-11-22T20:17:10+0100", title: "Lorem3"}}},
{node: {id: 123, title: "Lorem4", created_at: "2020-11-20T20:17:10+0100", description: "Lorem ipsum"}},
{node: {id: 124, title: "Lorem2", created_at: "2020-11-23T20:17:10+0100", description: "Lorem ipsum"}}
];
let array = []
posts.forEach(a => {
if (_.get(a.node, 'created_at')) {
array.push(a)
}
if (a.node.frontmatter) {
a.node.created_at = _.get(a.node.frontmatter, 'date')
array.push(a)
}
})
array.sort((a, b) => new Date(b.node.created_at) - new Date(a.node.created_at));
console.log("SORTED ARRAY", array)
My question: Is there a better way to perform this sort? Tried aliasing in Graphql, other sorting functions, etc.
GraphQL Query in Gastby:
const pageQuery = graphql`
query($skip: Int!, $limit: Int!) {
site {
siteMetadata {
title
}
}
sitePage {
path
}
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
limit: $limit
skip: $skip
) {
edges {
node {
excerpt(pruneLength: 300)
fields {
slug
}
frontmatter {
date
title
readingtime
description
tags
cover {
childImageSharp {
fluid(maxWidth: 170, maxHeight: 170, quality: 90) {
...GatsbyImageSharpFluid_withWebp_tracedSVG
}
}
}
}
}
}
}
articleList: allInternalLinks(
filter: {content: {ne: null }, alternative_id: {ne: null}}
limit: $limit
skip: $skip
) {
edges {
node {
is_archived
is_starred
user_name
user_email
user_id
is_public
alternative_id
title
url
content
created_at
updated_at
published_at
mimetype
language
reading_time
domain_name
preview_picture
tags {
label
}
}
}
}
}
`
JS Bin: https://jsbin.com/jetilahuxu/edit?js,console
Thanks for all responses! Sincerely
Create a function that can get the date or the fallback (using lodash or vanilla), and apply it to each object when you sort. You can use Date.parse()
to get the numeric value of a date and kip the object creation.
const posts = [{"node":{"excerpt":"Lorem1","fields":{"id":13},"frontmatter":{"description":"lorem","date":"2020-11-25T20:17:10+0100","title":"Lorem1"}}},{"node":{"excerpt":"Lorem3","fields":{"id":12},"frontmatter":{"description":"lorem","date":"2020-11-22T20:17:10+0100","title":"Lorem3"}}},{"node":{"id":123,"title":"Lorem4","created_at":"2020-11-20T20:17:10+0100","description":"Lorem ipsum"}},{"node":{"id":124,"title":"Lorem2","created_at":"2020-11-23T20:17:10+0100","description":"Lorem ipsum"}}]; const getDate = ({ node }) => node.created_at?? node.frontmatter.date const result = [...posts].sort((a, b) => Date.parse(getDate(b)) - Date.parse(getDate(a)) ); console.log(result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.