marshallswain / feathers-graph-populate

Add lightning fast, GraphQL-like populates to your FeathersJS API

Home Page:https://feathers-graph-populate.netlify.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Order of items not preserved in the populated array

kshitizshankar opened this issue · comments

Hey, Will the order of items be preserved in the populated array?

I am not sure whether this is something that is happening because of ObjectIds (am using Mongoose) or if the library doesn't maintain the order for any scenarios.

My original document is -

"tagIds": [
        "5f45e63e75589a147c264a4",
        "5f44bc0675589a147c26486",
    ],

The populated document is -

"tagIds": [
        "5f45e63e75589a147c264a4",
        "5f44bc0675589a147c26486",
    ],
"tags": [
    {
        "_id": "5f44bc0675589a147c26486",
        "name": "Tag 2"
    },
    {
        "_id": "5f45e63e75589a147c264a4",
        "name": "Tag 1"
    }
]

Thanks!

This is actually expected behavior. The library does not look into ordering to be fast by default. You could probably use the params object to add a sort to the query. I imagine it would probably make more sense to handle this on the client, though

Awesome!! Thanks for the quick reply 👍 - I wasn't sure if that was the expected behavior or if I messed up something on my end. Might be a good idea to add it to the documentation as well.

I am using the unpopulated ids to reorder the populated items in the setupInstance in the feathers vuex service. In case someone runs into it as well - created a function to do the ordering using lodash.

const orderPopulatedReferences = function (ResourceModel, data, unpopulatedKey, populatedKey) {
  if (!data) {
    throw new Error('Missing Data')
  }
  if (data[populatedKey] instanceof Array && data[populatedKey].length) {
    if (data[unpopulatedKey] instanceof Array && data[unpopulatedKey].length) {
      // Both are arrays
      const groups = groupBy(data[populatedKey], 'id')
      const orderedItems = map(data[unpopulatedKey], function (i) { return groups[i].shift() })
      data[populatedKey] = orderedItems.map(obj => new ResourceModel(obj))
    }
  }
  return data
}

@kshitizshankar that is a great solution. Thanks for sharing.