Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transform arguments are not passed correctly #137

Open
xyse opened this issue Feb 2, 2024 · 4 comments
Open

transform arguments are not passed correctly #137

xyse opened this issue Feb 2, 2024 · 4 comments

Comments

@xyse
Copy link

xyse commented Feb 2, 2024

When I execute the following code:

var createMapper = require("map-factory")

const testObject = {
    item: [
        {foo: true, bar: null},
        {foo: null, bar: null}
    `]`
}

function transform(input) {
    console.log(input)
}

const map = createMapper({alwaysTransform: true})
map('item.foo').to('foo', transform)
map('item.bar').to('bar', transform)
map.execute(testObject)

I would expect to get [true, null] as a transform argument for the foo mapping and [null, null] for the bar mapping. The problem is, I noticed when all the occurrences of an object's property in an array are null, we instead get undefined. So in this case we get [true, null] and undefined.

This way, using my custom transform I cannot transform the value of bar, as I cannot infer the length of the array from undefined. I think just passing the [null, null] array would be a better solution, as it gives more possibilities to map the null value in the custom transform.

The reason for this seems to be this part of the ./src/lib/object-mapper/get-key-value.js :

function scanArrayForValue_(arrayToScan, defaultValue) {

  for (const item of arrayToScan) {
    if (item !== undefined && item !== null) {
      return defaultValue;
    }
  }

  return undefined;

}
@jmac105
Copy link
Collaborator

jmac105 commented Feb 2, 2024

Hi @xyse thanks for raising this, I will have a look into this next week.

In the transform function are you looking to establish the length of the testObject.item array, or the number of elements in the testObject.item array where the object has a key of bar?

@xyse
Copy link
Author

xyse commented Feb 3, 2024

Well I want to map the null values so it would be best to just pass an array of them. When getting undefined I can assume every item.bar is null or undefined but I cannot map it as the length of the item[].bar array is not available for the transform.

If there is no bar key in one of the objects in the array I think it'd be best to pass a shorter array into the transform. For example if the second element of the item array had no bar key I'd get a one element array passed into the transform for source value item.bar.

There could also be an option like alwaysSet to choose whether to pass the values only where the key exists or even when it doesn't.

@jmac105
Copy link
Collaborator

jmac105 commented Feb 7, 2024

As a temporary workaround, I think the following may do what you need for now? This caters for item.bar being null, being undefined, or not being set at all (which is not quite the same as being set to undefined, if that matters...)

var createMapper = require("map-factory")

const testObject = {
    item: [
        {foo: true, bar: null},
        {foo: null, bar: null},
        {foo: false, bar: undefined},
        {foo: null}
    ]
};
function transform(input) {
    console.log('transform', input)
}

function transformSafe(objKey, inputArray) {
    const count = inputArray.filter(obj => Object.keys(obj).includes(objKey)).length;
    console.log(`${objKey} Count: ${count}`);
}

const map = createMapper({alwaysTransform: true})
map('item.foo').to('foo', transform)
map('item[]').to('bar', (...args) => transformSafe('bar', ...args))
map.execute(testObject)

@xyse
Copy link
Author

xyse commented Feb 8, 2024

It would be possible to do it like that, but for my use-case–I'm pulling the mappings from a database and automating the map('').to('') part by reading through each row of the db–it's not quite suited, there are also some other complications. I just forked it for now and changed the scanArrayForValue_ function in ./src/lib/object-mapper/get-key-value.js to only exclude undefined and not null values, so now it seems to be working for me.

But there should be a cleaner solution I think. The workaround u posted of course is fine for certain use-cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants