1

I am a beginner in JS and react. I am taking fullstackopen course on webdev and this is what I have to do (exercise at the end of the page): https://fullstackopen.com/en/part2/getting_data_from_server

I am required to show information about a country when I have a unique term for that country. I am unable to display this information on the page.

I have used console.log() function to make sure that I am reaching the piece of code (which I am), but that code is not being rendered.

I am using listHelper function in App component to do so. (I will work on the organization after solving this problem)

const listHelper = (arr) => {
    const showCountry = (country) => () => setNewTerm(country.name)
    const languageList = (languages) => (
      languages.map(language => (
        <div key={language.name}>
          <li>{language.name}</li>
        </div>
      ))
    )
    if(arr.length > 10) {
      return (
        <div>
          Too many matches, specify another filter
        </div>
      )
    }
    else if(arr.length > 1) {
      return arr.map(country =>
        <div key={country.name}>
          {country.name} <button onClick={showCountry(country)}>show</button>
        </div>
       )
    }
    else if(arr.length === 1) {
        axios
          .get(`http://api.openweathermap.org/data/2.5/weather?q=${arr[0].capital}&units=metric&APPID=551a172ca30189b3cfecbb6f6e312e45`)
          .then(response => {
            console.log('else if')
            return (
              <div>
                {console.log('in div')}
                <h1>{arr[0].name}</h1>
                <p>capital {arr[0].capital}</p>
                <p>population {arr[0].population}</p>
                <h2>languages</h2>
                <ul>
                  {languageList(arr[0].languages)}
                </ul>
                <img src={arr[0].flag} width='100' height='100' alt='country flag' />
                <h2>Weather in {arr[0].name}</h2>
                <strong>temperature:</strong> {response.data.main.temp}
                <img src={response.data.weather.icon} width='100' height='100' alt='current weather' />
                <strong>wind:</strong> {response.data.wind.speed} meter/sec direction {response.data.wind.deg}
              </div>
            )
          })
      }
  }

Expected outcome: https://i.stack.imgur.com/SFPj2.jpg Current outcome: https://i.stack.imgur.com/4aXk0.jpg

dj48
  • 23
  • 6
  • You mentioned react. Is this a function component or a render method of a class? Maybe render is not triggered due to props not changing. – Ivan Rubinson Jun 30 '19 at 08:45
  • Thanks for the quick reply. I believe that it is a render method of App component. – dj48 Jun 30 '19 at 08:50
  • 2
    This is something beginners struggle with a lot, it's not just you. :-) Your `return` in the `then` callback just returns a value from that callback, but since nothing is chained on that promise, it doesn't go anywhere. `listHelper` can't directly return the `axios` result because it just *starts* the process, which is asynchronous; it returns before the process completes. Instead, `listHelper` should return the promise from `axios`. In the modern world, the easiest way to do that is to make `listHelper` an `async` function and use `await`. Whatever uses `listHelper` will have to handle... – T.J. Crowder Jun 30 '19 at 08:50
  • ...the asynchronous nature of things as well. – T.J. Crowder Jun 30 '19 at 08:51
  • Here's an idea of how it looks with an `async` function: https://pastebin.com/573dKN9a and how it looks using promises explicitly (see the lines tagged with `***` comments). In both cases, `listHelper` returns a promise, which means the caller needs to use `await` (if it's `async`) or `then` (if not), and must handle the fact that it gets the result asynchronously. Happy coding! – T.J. Crowder Jun 30 '19 at 08:55

0 Answers0