Reputation: 3526
I am trying to create a custom string to be shown to the user, which is based on two variables.
Here is the example that I am trying to build:
let url1;
let url2;
if (containsData1) {
url1 = "http://test";
}
if (containsData2) {
url2 = "http://test2";
}
let finalString = '';
if (url1 && url2) {
finalString = 'The url 1 is ' + url1 + ' and url 2 is ' + url2;
} else if (!url1 && url2) {
finalString = 'There isnt data for url1. Url2 is ' + url2;
} else if (url1 && !url2) {
finalString = 'The url 1 is ' + url1 + '. There isnt data for url2';
} else if (!url1 && !url2) {
finalString = 'There isnt data for url1. There isnt data for url2';
}
However I would like to this in a proper way, without using this bunch of if elses, any suggestions on how to accomplish this?
Thanks.
Upvotes: 3
Views: 1209
Reputation: 28983
It's better to treat that as two different conditional strings and then join them together:
let string1;
if (url1) {
string1 = 'The url 1 is ' + url1 + '.';
} else {
string1 = 'There isnt data for url1.';
}
let string2;
if (url2) {
string2 = 'Url2 is ' + url2;
} else {
string2 = 'There isnt data for url2';
}
let finalString = string1 + string2;
This allows you to reason about the resulting string in a more straight forward way than considering each possible case at once. With only two variables, you have 4 possible outcomes, with 4 you'd have 16.
Separating each variable means that you don't need to care what the other possibilities are when you generate each substring.
You can further make that simpler to think about by using templates. In that case you can separate the string generation logic elsewhere so you focus on different things in different areas
For example you might want to standardise the messages and have something like:
function makeSubMessage(url, name) {
if (url) {
return `The $[name} is ${url}`;
} else {
return `No data for ${name}`;
}
}
/* ... */
let string1 = makeSubMessage(url1, "Url1");
Which will allow you to more easily swap what the format of the messages is without having to touch how they are then presented.
When you're presenting them, you might want to have each message on a separate line, than simply one string, so the result need not rely on what the submessages are:
function(urls) {
let finalString = "";
for (let i = 0; i < urls.length; i++) {
let subMessage = makeSubMessage(urls[i], "Url" + (i + 1));
finalString += subMessage;
finalString += "\n"
}
return finalString;
}
Or you can change this implementation entirely:
function(urls) {
let finalString = urls
.map((url, i) => makeSubMessage(url, "Url" + (i + 1)))
.join("\n")
return finalString;
}
or change to display them as HTML bulletpoints, perhaps:
function(urls) {
let finalString = urls
.map((url, i) => makeSubMessage(url, "Url" + (i + 1)))
.map(subMessage => `<li>${subMessage}</li>`)
.join("<br/>")
return `<ul>${finalString}</ul>`;
}
Or anything else. Point being that the concerns are now separated.
Upvotes: 0
Reputation: 872
I'm sure we could get even more precise with the ternary statements:
let url1 = containsData1;
let url2 = containsData2;
let finalString = url1 ? `The url 1 is ${url1}` : 'There is no data for url 1';
if (url1 && url2) {finalString += ` and url 2 is ${url2}.`}
if (!url2) {finalString += '. There is no data for url2.'}
Upvotes: 0
Reputation: 6446
You could use ternary statements:
let url1;
let url2;
url1 = "http://test";
url2 = "http://test2";
let finalString = (url1 ? 'The url 1 is ' + url1 : 'There isnt data for url1.') +
(url1 && url2 ? ' and t' : ' T') +
(url2 ? 'he url 2 is ' + url2 : 'There isnt data for url2.');
console.log(finalString)
Upvotes: 3
Reputation: 669
1st - Use ES6 string templates
let url1;
let url2;
if (containsData1) {
url1 = "http://test";
}
if (containsData2) {
url2 = "http://test2";
}
let finalString = '';
if (url1 && url2) {
finalString = `The url 1 is ${ url1 } and url 2 is ${ url2 }`;
} else if (!url1 && url2) {
finalString = `There isnt data for url1. Url2 is ${ url2 }`;
} else if (url1 && !url2) {
finalString = `The url 1 is ${ url1 }. There isnt data for url2`;
} else if (!url1 && !url2) {
finalString = 'There isnt data for url1. There isnt data for url2';
}
2nd - unify and extract
const urls = {
url1: containsData1 ? "http://test" : null,
url2: containsData2 ? "http://test" : null,
}
const assertData = name => urls[name] ? `${name} is ${urls[name]}` : `isnt data for ${name}`
let finalString = `${assertData('url1')}. ${assertData('url2')}`
Upvotes: 0