pitchdiesel
pitchdiesel

Reputation: 309

Dynamically create a links from an array of items

I need to create a ul of links based on the valued in an array. The links are created but the href attribute is being randomly assigned and doesn't correspond to the actual value I'm passing in to my getUrl function.

Here is my code so far:

  getURL (type) {
    let url
    switch (type) {  
      case 'Yahoo':
        url = 'https://www.yahoo.com/'

      case 'Bing':
        url = 'https://www.bing.com/'

      default:
        url = 'https://www.google.com'
    }
    return url
  }

and the render:

  render () {
    let { expandList } = this.state

    let listItems = [
      'Google',
      'Bing',
      'Yahoo'
    ]

    let list = expandList
      ? listItems.map((item, index) => {
          return (
            <li key={index}>
              <a href={this.getURL(item)} target='_blank'>
                {item}
              </a>
            </li>
          )
        })
      : ''

    return (
      <div>
        <ul>{list}</ul>
      </div>
    )
  }

Upvotes: 0

Views: 306

Answers (2)

Eric
Eric

Reputation: 2705

switch basically tries to match type with the argument to the case, and when there's a match, it will execute the codes in all the cases below it unless you explicitly break it.

default is a catch-all in case none of the cases match the type.

The correct way to do it with switch would be breaking out of it after the case statement is executed. One way of doing this is by inserting break:

getURL (type) {
    let url
    switch (type) {  
      case 'Yahoo':
        url = 'https://www.yahoo.com/'
        break
      case 'Bing':
        url = 'https://www.bing.com/'
        break
      default:
        url = 'https://www.google.com'
    }
    return url
  }

You can also definitely return the url in the case statement as Ori Drori suggested, which will not only break out of the switch, but also break out of the function.

I would also recommend ending your statements with a semicolon. Even though it's optional, it can prevent unexpected errors.

Also, I would recommend lowercasing type with type.tolowercase() and match it with lowercase strings.

If all getURL does is to map the name of the website to the url, an alternative with less code would be using an object:

var nameToUrlMap = {
  'yahoo': 'https://www.yahoo.com/',
  'bing': 'https://www.bing.com/',
};

and then use it like:

var type = 'Yahoo';
var lowercasedType = type.tolowercase();
var url = nameToUrlMap[lowercasedType] || 'https://www.google.com/'; // falls back to google if name doesn't exist in nameToUrlMap
console.log(url); // "https://www.yahoo.com/"
console.log(nameToUrlMap['abcd'] || 'https://www.google.com/'); // "https://www.yahoo.com/"

You can wrap it in a function if you want:

var nameToUrlMap = { 
  'yahoo': 'https://www.yahoo.com/',
  'bing': 'https://www.bing.com/',
};

function getURL(type) {
  var lowercasedType = type.tolowercase();

  var url = nameToUrlMap[lowercasedType] || 'https://www.google.com/'; // falls back to google if name doesn't exist in nameToUrlMap

}

You can use const or let in place of var as well.

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 192287

You need to break after each case or return from it. If you don't it will always continue to default, and return the google url.

function getURL(type) {
  switch (type) {
    case 'Yahoo':
      return 'https://www.yahoo.com/'

    case 'Bing':
      return 'https://www.bing.com/'

    default:
      return 'https://www.google.com'
  }
}

console.log(getURL('Yahoo'));

console.log(getURL('Bing'));

Upvotes: 3

Related Questions