0

I have this code:

var newStatus = (status, subStatus) => {
  if(status === 'CREATED' && 
         (subStatus === 'subStatus1' || 'subStatus2' || 'subStatus3')){
    return 'CONFIRMED';
  } else if(status === 'CANCELLED' && 
         (subStatus === 'subStatus4' || 'subStatus5' || 'subStatus6')){
    return 'REMOVED';
  } else if(status === 'REVIEW' && 
        (subStatus === 'subStatus7' || 'subStatus8' || 'subStatus9')){
    return 'CHECKED';
  }
}

<div>newStatus('CREATED', 'subStatus2')</div>

In this case, the div must render with the value 'CONFIRMED'. I believe this logic has a bug and I need 'subStatus ' to be an array and check somehow against each element, but how can I achieve this?

Can someone help me with a solution on how to implement this logic correctly?

Sarun UK
  • 6,210
  • 7
  • 23
  • 48
  • 1
    We can't help resolve a logic issue without you explaining in detail what the expected result is, and how the current code's result differs from that. – DBS Sep 28 '20 at 08:53
  • Also `subStatus === 'subStatus7' || 'subStatus8'` isn't how you would compare a variable against multiple strings, you need `yourVar === "a" || yourVar === "b"` (The comparison needs to be included in each of the "ors") – DBS Sep 28 '20 at 08:56
  • Does this answer your question? [Javascript: The prettiest way to compare one value against multiple values](https://stackoverflow.com/questions/9121395/javascript-the-prettiest-way-to-compare-one-value-against-multiple-values) – 04FS Sep 28 '20 at 08:57
  • I need to combine status and subStatus and return a third predefined status based on the combination of those two ones. Like in my example, 'CREATED' and 'subStatus2' must return a new string 'CONFIRMED'. I think my solutions it's not checking correctly the subStatus.. I'm thinking on implementing subStatus as an array and then check against each element of array? But I'm not sure I know how. –  Sep 28 '20 at 08:57
  • try `['subStatus1', 'subStatus2' , 'subStatus3'].includes(status)` etc – Jaromanda X Sep 28 '20 at 09:02
  • @04FS So from that post I understand I need to write something like this in order to check correctly: `if(status === 'CREATED' && (subStatus === 'subStatus1' || subStatus === 'subStatus2' || subStatus === 'subStatus3')){ return 'CONFIRMED';` this can be a possible solution? –  Sep 28 '20 at 09:05
  • 1
    @Christian you can't post multiline code in comments – Sugar Sep 28 '20 at 09:07
  • 1
    [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) might help – Sugar Sep 28 '20 at 09:09

3 Answers3

0

You can create a map of the sub-statuses and then, for the unique sub-status, check that it also has the expected status and, if so, return the new status:

subStatuses = {
  "subStatus1": { "expectedStatus": "CREATED",   "newStatus": "CONFIRMED" },
  "subStatus2": { "expectedStatus": "CREATED",   "newStatus": "CONFIRMED" },
  "subStatus3": { "expectedStatus": "CREATED",   "newStatus": "CONFIRMED" },
  "subStatus4": { "expectedStatus": "CANCELLED", "newStatus": "REMOVED" },
  "subStatus5": { "expectedStatus": "CANCELLED", "newStatus": "REMOVED" },
  "subStatus6": { "expectedStatus": "CANCELLED", "newStatus": "REMOVED" },
  "subStatus7": { "expectedStatus": "REVIEW",    "newStatus": "CHECKED" },
  "subStatus8": { "expectedStatus": "REVIEW",    "newStatus": "CHECKED" },
  "subStatus9": { "expectedStatus": "REVIEW",    "newStatus": "CHECKED" },
}

function newStatus( status, subStatus )
{
  if ( subStatus in subStatuses && status === subStatuses[subStatus].expectedStatus )
  {
    return subStatuses[subStatus].newStatus;
  }
  return undefined;
}

element = document.getElementById( "to_check" );
element.innerText = newStatus(
  element.getAttribute( "status" ),
  element.getAttribute( "substatus" )
);
<div id="to_check" status="CREATED" substatus="subStatus2" />
MT0
  • 143,790
  • 11
  • 59
  • 117
0

You could use an object to map each subarray to the correct status, this way you don't need to add multiple if statements for all the possible outcomes. You can just update the object.

const statusMap = {
  created: {
    sub: ['subStatus1', 'subStatus2', 'subStatus3'],
    value: 'CONFIRMED',
  },
  cancelled: {
    sub: ['subStatus4', 'subStatus5', 'subStatus6'],
    value: 'REMOVED',
  },
  review: {
    sub: ['subStatus7', 'subStatus8', 'subStatus9'],
    value: 'CHECKED',
  },
};

const newStatus = (status, subStatus, statusMap) => {
  // Turn the status to lowercase
  const lower = status.toLowerCase();
  
  // Return if it doesn't exist
  if(!statusMap[lower]) return;
  // Get sub array and return value
  const {sub, value} = statusMap[lower];
  // If the item exist in the sub array return the value
  if(sub.includes(subStatus)) return value;
}

const status1 = newStatus('CREATED', 'subStatus2', statusMap);
const status2 = newStatus('CANCELLED', 'subStatus6', statusMap);
const status3 = newStatus('REVIEW', 'subStatus7', statusMap);

console.log(status1);
console.log(status2);
console.log(status3);
Reyno
  • 6,119
  • 18
  • 27
0

There are big issues with your code. This comparison:

subStatus === 'subStatus1' || 'subStatus2' || 'subStatus3'

will return true if subStatus has the value of 'subStatus1'. If not, it will return true because 'subStatus2' will be interpreted as true.
If you want to check if subStatus has one of the values of subStatus1 or subStatus2 or subStatus1, then you should include those values in an array like this:

const SUB_STATUSES = ['subStatus1', 'subStatus2', 'subStatus3'];

then, you will have to use JavaScript's array method includes() like this:

SUB_STATUSES.includes(subStatus)

that will return true if the value of subStatus is included in SUB_STATUSES. You can check the documentation here Array.prototype.includes()

Your code should look something like this after the modifications:

const SUB_STATUSES1 = ['subStatus1', 'subStatus2', 'subStatus3'];
const SUB_STATUSES2 = ['subStatus4', 'subStatus5', 'subStatus6'];
const SUB_STATUSES3 = ['subStatus7', 'subStatus8', 'subStatus9'];
const newStatus = (status, subStatus) => {
    if (
        status === 'CREATED' && SUB_STATUSES1.includes(subStatus)
    ) {
        return 'CONFIRMED';
    }
    if (
        status === 'CANCELLED' && SUB_STATUSES2.includes(subStatus)
    ) {
        return 'REMOVED';
    }
    if (
        status === 'REVIEW' && SUB_STATUSES3.includes(subStatus)
    ) {
        return 'CHECKED';
    }
};

Apart from that, there might be another issues because there might be cases that slips through these conditions.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Antenaina
  • 154
  • 2
  • 12
  • Yes, this was the answer I was looking for. Thank you very much for your help. –  Sep 28 '20 at 09:55