61

I'm working on a small API and I want to update the data using HTTP PATCH REQUEST without using a bunch of if statements. I'm trying to fill the outgoing data object with the changed data only.

update() {
    let prop1 = hasBeenChanged.prop1 ? changedData.prop1 : null;
    // ...
    let propN = hasBeenChanged.propN ? changedData.propN : null;

    let data: ISomething = {
        // something like --> property != null ? property: property.value : nothing
    }
}

Is there any way to create the data object dynamically?

4 Answers 4

68

You could use Object.assign in combination with the ternary operator:

let data = Object.assign({},
  first === null ? null : {first},
  ...
);

This works because Object.assign will skip over null parameters.

If you are sure that the property value is not going to be "falsy", then it would be bit shorter to write:

let data = Object.assign({},
  first && {first},
  ...
);

Assuming the object is going to be stringified at some point, since stringification ignores undefined values, you could also try

let data = {
  first: first === null ? undefined : first,
  ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I've got it now. I forgot to tell that I'm using typescript and I thought it's going to be similar, but there is no Object.assign function in the ObjectConstructor of typescript when I'm compiling to ES5. I did it with your tip about the stringified data. When I set the data to undefined and not null, they haven't been stringified which was great and easy! Thank you!
Should the || in the first code segment be : per typical ternary construction? Or is this some other sorcery that I'm unfamiliar with?
59

Depending on the JS version you are using, you can use the spread operator ...

const getData = data => ({
  ...data.first  && { 'Custom First Prop Name': data.first },
  ...data.second && { 'Custom Second Prop Name': data.second },
  ...data.third  && { third: data.third },
  ...data.fourth && { fourth: data.fourth },
});

Comments

13

Non-inline solution

If you don't need to add the value inline, it is pretty straightforward and clean to write your assignment like this.

const val1 = 1
const val2
const data = {}

val1 && (data.a = val1) // 1
val2 && (data.b = val2) // Not added
// data = { a : 1 }

NOTE: This will not work if the value is falsey

1 Comment

Paranthesis was what I missed
2

Easy way:

const example = {
   ...(foo?.bar && {nested: 1})
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.