0

So I'm having this little generator, the info that get displayed should correspond to what values are populated on the database, the example below is a physical address

this.setState({
   companyEmail: json.data.companyEmail,
   company: json.data.company,
   line1: json.data.line1,
   line2: json.data.line2,
   city: json.data.city,
   ... 
});

So I could initialize those values with null, undefined or "" it does not matter, on the fetch request the typeof those empty values turn to undefined.

Firebase don't like that, for me it cause no issue, I could hide the element by checking if it's true or false like so

{line1 && <span>{line1}<br /></span>}
{line2 && <span>{line2}<br /></span>}

Well I mean it works until I tried updating the database, I got this error

Error: Reference.set failed: First argument contains undefined in property 'master.business.info.line2'

What I want to do is kindof turning undefined to null, because when sending null remove the child from the db, it's treated like a real value.

On the server side, it's regular db update

master.update({
   company: company,
   line1: line1,
   line2: line2,
   city: city,
   ... 
})
.then(() => {
   response.sendStatus(200);
}).catch(function (err) {
   console.log(err);
   response.sendStatus(204);
});

I could use if statement and setState accordingly but that's too much work. I need to make to fetch request because I need those values, it's a form to edit info.

Also using empty strings like "" is not good, it gets display inside span, paragraph or whatever.

This is not a duplicate, on react.js my goal is to not setState for undefined values and keep the init values on the constructor.

  • You wan't that key to be there or you want to remove key itself from object ? i.e if line2 is undefined you want it on object passed to update on or not ? – Code Maniac Jun 01 '19 at 20:22
  • Possible duplicate of [Representing null in JSON](https://stackoverflow.com/questions/21120999/representing-null-in-json) – Randy Casburn Jun 01 '19 at 20:24
  • so `company: company || null,` doesn't work? – Randy Casburn Jun 01 '19 at 20:28
  • It's a form, on mount value it's set to undefined because of the fetch request, on change it turns to string, I want to get rid of undefined to turn it into null that way, if you update line1 and keep line2 as is, you wouldn't mess with db –  Jun 01 '19 at 20:31

2 Answers2

1

Maybe if you change your setState like this:

const {companyEmail, company, line1, line2, city} = json.data;
this.setState({
   companyEmail,
   company,
   line1,
   line2,
   city,
   ... 
});

If any var doesn't have value, it doesn't add to state.

Here, you could check before update. Try something like this:

const objUpdate = {
   company: company,
   line1: line1,
   line2: line2,
   city: city,
   ... 
};
const cloneObjUpdate = {...objUpdate};
Object.keys(objUpdate).forEach(key=>{
    if(!Boolean(cloneObjUpdate[key])) delete cloneObjUpdate[key];
});

master.update(cloneObjUpdate);

For keep object with null values, just remove delete and set a null value:

const objUpdate = {
   company: company,
   line1: line1,
   line2: line2,
   city: city,
   ... 
};
const cloneObjUpdate = {...objUpdate};
Object.keys(objUpdate).forEach(key=>{
    if(!Boolean(cloneObjUpdate[key])) cloneObjUpdate[key] = null;
});
narcello
  • 501
  • 4
  • 11
  • Well I have to try that, for me it looks there's no difference, you just make it compact. Sorry it's not working, still getting undefined as typeof –  Jun 01 '19 at 20:24
  • I'm sorry, check my answer again... I've made a update – narcello Jun 01 '19 at 20:35
  • Do you know how can I keep those values but set them to null? I am running into some issues when editing the db with empty strings like line2: '', your function remove the child from the obj and the db dont get updated because the obj does not contain that value:null –  Jun 01 '19 at 21:00
0

I started with changing undefined to null for Firebase’s sake, but then I realized it was easier to just remove the undefined keys altogether:

const removeUndefinedKeys = (collection) => Object.keys(collection).reduce((result, key) => (
  ![undefined, null].includes(collection[key])
    ? { ...result, [key]: collection[key] }
    : result
), {})
Tom Söderlund
  • 4,743
  • 4
  • 45
  • 67