flamelink / flamelink-js-sdk

🦊 Official Flamelink JavaScript SDK for both the Firebase Realtime database and Cloud Firestore
https://flamelink.github.io/flamelink-js-sdk
MIT License
43 stars 5 forks source link

Populating single relational fields doesn't seem to work. #130

Closed csabaxyz closed 4 years ago

csabaxyz commented 4 years ago

Hey, Yesterday I commented on this issue with the problem: https://github.com/flamelink/flamelink/issues/90 But I just realized that that repo is for the older version of the plugin.

Anyway, the problem seems to be that I have a relational field that is set to single (multiple:false), and I'm trying to populate only certain fields with this code:

  const data = await db.content.get({
    schemaKey: 'videos',
    fields: ['id', 'videoTitle', 'nextVideo'],
    populate: [{
      field: 'nextVideo',
      fields: [ 'id' ]
    }]
  })

And this is the result that I get with this:

{
  "id": "some-id",
  "videoTitle": "some video title",
  "nextVideo": {
    "isLive": {},
    "order": {},
    "dateExpire": {},
    "artists": {},
    "_fl_meta_": {},
    "videoThumbnail": {},
    "videoTitle": {},
    "id": {}
  }
}

As you can see every key has an empty object as their value. I tried to find the source of this problem, and I think it is related to this code: https://github.com/flamelink/flamelink-js-sdk/blob/a637c0b26fa8e63fa0e20ec3d7986e9519147381/packages/utils/src/index.ts#L437-L444

It looks like this part gets the data in a format like this:

{
  "isLive": true,
  "order": 5,
  "dateExpire": "...",
  "artists": [ ... ],
  "_fl_meta_": { ... },
  "videoThumbnail": { ... },
  "videoTitle": "title",
  "id": "some-id"
}

And when the reduce runs, it will get the val and key values like this:

key: isLive, val: true
key: order, val: 5

And as the pickFields will return an empty object, every key will end up like that. Possible fix would be to determine if the given object is a single piece of content or part of a result query, and then run the pluckResultFields according to that logic.

csabaxyz commented 4 years ago

As a quick fix, something like this can be used:

  // TODO: Write our own "pick" that can work with an array of strings or an array of objects for nested objects
  const pickFields = pick(fields)

  // If the resultSet is a flamelink object
  if (resultSet.hasOwnProperty('_fl_meta_')) {
    return pickFields(resultSet)
  }

  // If resultSet is an array of objects, we just pluck the given fields from each object
  if (isArray(resultSet)) {
dewetvdm commented 4 years ago

Hi @csabaxyz

Thanks for the detailed explanation, we will have a look at it soonest and report progress here 👍

csabaxyz commented 4 years ago

Hey @dewetvdm, Can confirm, 1.0.0-alpha.31 fixes the issue for us.