0

I am slowly learning JS & React, and trying to build an app that pulls weather data from various locations and displays it on a Monday.com dashboard. Still a very long way to go, but putting the puzzle pieces together 1 by 1.

I have a working app that gets the weather based on lattitude & longitude, and then displays it on the page.

Here is my code for App.js

import './App.css';
import React, { useEffect, useState } from "react";
import { Dimmer, Loader } from 'semantic-ui-react';
import Weather from './components/weather';


export default function App() {

const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState([]);


// this useEffect will only fire when the component mounts (once)
useEffect(() => {
    navigator.geolocation.getCurrentPosition(location => {
        setLat(location.coords.latitude);
        setLong(location.coords.longitude);
    });
}, [])

// this useEffect will be called once the component mounts + when any dependency changes (lat/long)
useEffect(() => {
    fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
        .then(res => res.json())
        .then(result_geo => {
            setData(result_geo)
            console.log("Latitude is:", lat)    // (GL)
            console.log("Longitude is:", long)  // (GL)
            console.log(result_geo);
    });
}, [lat, long])


  return (
    <div className="App">

      {(typeof data.main != 'undefined') ? (
        <Weather weatherData={data}/>
      ): (
        <div>
          <Dimmer active>
            <Loader>Loading..</Loader>
          </Dimmer>
       </div>
      )}
    </div>
  );
}

And here is my code for weather.js

import React from 'react';
import '../styles.css';
import { Card } from 'semantic-ui-react'
import moment from 'moment';

const CardExampleCard1 = ({weatherData}) => (
  <div className="Cards">
      <Card className="card1">
        <Card.Content>
            <Card.Header className="header">Location: {weatherData.name}</Card.Header>
            <p>{moment().format('dddd')}, {moment().format('LL')} {moment().format('HH:mm')}</p>
            <br></br>
            <p>Temperature: {weatherData.main.temp} &deg;C</p>
            <p>Sunrise: {new Date(weatherData.sys.sunrise * 1000).toLocaleTimeString('en-IN')}</p>
            <p>Sunset: {new Date(weatherData.sys.sunset * 1000).toLocaleTimeString('en-IN')}</p>
            <p>Description: {weatherData.weather[0].main}</p>
            <p>Humidity: {weatherData.main.humidity} %</p>
            <br></br>
        </Card.Content>
      </Card>


  </div>
)


export default CardExampleCard1;

The next thing I am trying to figure out is how to display multiple cards (using { Card } from 'semantic-ui-react' ) for various different locations.

I am able to retrieve the weather for an additional location by duplicating the API call and changing the lat&lon (probably there's a better way), and I can store that into a variable, but I don't know how to pass that to weather.js in my return function. I have tried multiple things but it fails. And also how to update my weather.js code to then display different cards.

ANy help would be appreciated - I've been stuck on this for hours.

Eventually, I need to read location names from a monday.com board, do an API call to retrieve their geolocations, then API calls to get their weather, and then display the weather. And this can be for a variable number of locations.

2 Answers 2

1

You can use the map function on an array like this below. Assuming the data in state is an array, and the response from server is a JSON object, then when calling for the second time, your array is updating by adding new object in it.

        <div>
           {data.map(item => <Weather weatherData={item}/>)}
        </div>

import './App.css';
import React, { useEffect, useState } from "react";
import { Dimmer, Loader } from 'semantic-ui-react';
import Weather from './components/weather';


export default function App() {

const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState([]);


// this useEffect will only fire when the component mounts (once)
useEffect(() => {
    navigator.geolocation.getCurrentPosition(location => {
        setLat(location.coords.latitude);
        setLong(location.coords.longitude);
    });
}, [])

// this useEffect will be called once the component mounts + when any dependency changes (lat/long)
useEffect(() => {
    fetch(`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`)
        .then(res => res.json())
        .then(result_geo => {
            setData(result_geo)
            console.log("Latitude is:", lat)    // (GL)
            console.log("Longitude is:", long)  // (GL)
            console.log(result_geo);
    });
}, [lat, long])


  return (
    <div className="App">

      {(typeof data.main != 'undefined') ? (
        <div>
           {data.map(item => <Weather weatherData={item}/>)}
        </div>
      ): (
        <div>
          <Dimmer active>
            <Loader>Loading..</Loader>
          </Dimmer>
       </div>
      )}
    </div>
  );
}

Sign up to request clarification or add additional context in comments.

1 Comment

I have tried this but not sure how exactly to implement. When I redo the UseEffect call to get a second location's weather it returns the data, but it does not show anything on screen, and not sure how to update my weather component to cater for it.
0

"display multiple cards": display arrays of Components in React. So to display multiple you can use Array.map().

Ex:

const people = [
  { name: 'Harry' },
  { name: 'Ron' },
  { name: 'Hermione' },
]

...

return (
  <>
    {people.map((e, idx) => {
      return (<span key={idx}>{e.name}</span>)
    })}
  </>
)

"pass that to weather.js": Not sure to get it. But when your parent component update a state the childrens using that state are going to rerender. So using a setData() when you get your new api response should update weatherData in the child component.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.