user3142695
user3142695

Reputation: 17352

How to empty all following fields of an object if a value gets changed?

I'm using a dataset, which has the fields continent, country, city and `street. As you can imagine, each field depends on the previous field.

Now assume there is a (partial) completed dataset and the user changes the country value. Then all following fields have to be empty.

This is how I am doing that (in my case the data is stored as a state in a react component - but that should not matter here). But to me this looks very undynamic. I hope this can be done a bit more 'programatical'.

My problem is, that I cannot just iterate the object, as the order of the fields is not fixed in an js object. It would be in an array, but this is not the case here...

if (data.name === 'continent') {
  this.setState({
    continent: undefined,
    country: undefined,
    city: undefined,
    street: undefined
  })
} else if (data.name === 'country') {
  this.setState({
    country: undefined,
    city: undefined,
    street: undefined
  })
} else if (data.name === 'city') {
  this.setState({
    city: undefined,
    street: undefined
  })
} else if (data.name === 'street') {
  this.setState({
    street: undefined
  })
}

Upvotes: 2

Views: 59

Answers (3)

Amit
Amit

Reputation: 46351

You could use a fall-through switch:

switch(data.name) {
  case 'continent':
    this.setState({ continent: undefined });
  case 'country':
    this.setState({ country: undefined });
  case 'city':
    this.setState({ city: undefined });
  case 'street':
    this.setState({ street: undefined });
}

Upvotes: 1

mhodges
mhodges

Reputation: 11126

Since the fields do have hierarchy and order, you can store the names in an array. Then take the field changed and all subsequent fields and set them to undefined, and then use Object.assign() to create your new state, like so:

var data = {name: "country"};
var fields = ["continent", "country", "city", "street"];
var state = {
  continent: "North America",
  country: "United States",
  city: "Orlando",
  street: "123 Main Street"
}
function clearFields (fieldName) {
  var fieldIndex = fields.indexOf(fieldName);
  var updatedState = {};
  if (~fieldIndex) {
    updatedState = fields.slice(fieldIndex).reduce(function (newState, currField) {
      newState[currField] = undefined;
      return newState;
    }, {});
  }
  return Object.assign({}, state, updatedState);
}

console.log("Clear Continent...");
console.log(clearFields("continent"));

console.log("Clear Country...");
console.log(clearFields("country"));

console.log("Clear City...");
console.log(clearFields("city"));

console.log("Clear Street...");
console.log(clearFields("street"));

// to update react state...
//this.setState(clearFields(data.name));

Upvotes: 1

Keith
Keith

Reputation: 24221

Although object literal ordering is undefined, array ordering is not.

So if we use an Array to find the index to start undefining, we can then continue from that index.

Below is an example.

let
  seri = ['continent', 'country', 'city', 'street'];
  
  
function clear(name, obj) {
  let p = seri.indexOf(name);
  for (let l = p; l < seri.length; l ++) 
     obj[seri[l]] = undefined;
  return obj;
}

var
  all = {
    continent: 'continent',
    country: 'country',
    city: 'city',
    street: 'street'  
  };

seri.forEach((c) => {
  console.log(`clear ${c}`);
  console.log(clear(c, Object.assign({},all)));
});

Upvotes: 0

Related Questions