2 years ago

#73058

test-img

Gian Paulo Zamora

How to get a search value from a React component to a server backend

I recently updated a weather dashboard project that I was working on to have a server backend, that I could just pull the API json values from said server page (in order to hide the api key I need to utilize the weather api). Since my React project requires entering a searched city value or zipcode and the API request being made requires said searched value to be submitted into the site request, I am struggling with how to get said value from the client side to the server side. Whenever I have tried to connect a callback function which can just grab the value from the React component after the user enters it, I get a React error that states

"Module not found: You attempted to import which falls outside of the project src/ directory. Relative imports outside of src/ are not supported"

My question is, how am I meant to connect this? Below is my code for the component collecting the search value, overview.js, where the function getSearch receives the value from a child component:

import React from 'react';
import './overview.css';
import { RecentSearches } from '../Recent Searches/recentSearches';
import { Hourly } from '../Hourly/hourly';
import { Fiveday } from '../5 Day Forecast/fiveday';

export function Overview() {

    // this callback function receives the searched city entered from recentSearches and applies it to fetchForecast
    const getSearch = async (searchedCity) => {
        console.log(searchedCity);
        fetchForecast(searchedCity);
    }; 

    async function fetchForecast(city) {
        var BASE_URL = `localhost:8000/forecast`;
    
        const response = await fetch(BASE_URL);
        const data = await response.json();
    
        // collects all of the current weather info for your search
        const currentTempInfo = {
            city: data.location.name, 
            state: data.location.region, 
            epochDate: data.location.localtime_epoch, 
            message: data.current.condition.text, 
            wicon: data.current.condition.icon, 
            currentTemp: data.current.temp_f,
            currentHighTemp: data.forecast.forecastday[0].day.maxtemp_f,
            currentLowTemp: data.forecast.forecastday[0].day.mintemp_f,
            feelsLike: data.current.feelslike_f,
            humidity: data.current.humidity,
            rainLevel: data.current.precip_in,
            // hourlyTemps is an array, starts from midnight(index 0) and goes every hour until 11 pm(index 23)
            hourlyTemps: data.forecast.forecastday[0].hour.map((entry) => {
                let epochTime, temp;
                [epochTime, temp] = [entry.time_epoch, entry.temp_f];
                return [epochTime, temp];
            })
        };
    
        // console.log(currentTempInfo);
    
        const daycardInfo = [];
        // this for loop triggers and creates an array with all necessary values for the 
        function daycardForLoop() {
            for (let x=0; x < 3; x++) {
                const fcDayDates = data.forecast.forecastday[x].date_epoch;
                const dayInfo = data.forecast.forecastday[x].day; 
                const dayValues = {
                    dates: fcDayDates, 
                    message: dayInfo.condition.text, 
                    wicon: dayInfo.condition.icon, 
                    maxTemp: dayInfo.maxtemp_f, 
                    minTemp: dayInfo.mintemp_f, 
                    avgTemp: dayInfo.avgtemp_f
                };
                // pushes dayValues object into daycardInfor array
                daycardInfo.push(dayValues);
            };
        }; 
        
        daycardForLoop();
    
        // this updates the state with the forecast for the city entered
        const newData = {
            currentTempInfo: currentTempInfo,
            daycardInfo: daycardInfo
        };
    
        // this spits out the newly created forecast object
        return newData;
    };

    return (
        <div>
            <div className='jumbotron' id='heading-title'>
                <h1>Welcome to <strong>Weathered</strong>!</h1>
                <h3>A Simple Weather Dashboard </h3>
            </div>

            <div className='container-fluid' id='homepage-skeleton'>
                <div className='d-flex' id='center-page'>
                    <RecentSearches getSearch={getSearch}/>
        
                    <Hourly />
                </div>
            </div>

            <Fiveday />        
        </div>
    )
};

Here is my server code, index.js, where you can see that I need to fill in the params value of "q" that you can find in the get request for the "/forecast" page:

const PORT = 8000;
const express = require('express');
const cors = require('cors');
const axios = require('axios');

require('dotenv').config();

const app = express();

// this callback function receives the searched city entered from recentSearches and applies it to fetchForecast
// update: this callback function now passes the search to the backend for the url search to parse the new data
// export const getSearch = async (searchedCity) => {
//     fetchForecast(searchedCity);
// }; 

app.get('/', (req, res) => {
    res.json('hi');
});

app.get('/forecast', (req, res) => {    
    const options = {
        method: 'GET',
        url: `http://api.weatherapi.com/v1/forecast.json?key=${process.env.REACT_APP_API_KEY}`,
        params: {
            q: "*** I need to get the search value here ***",
            days: 3,
            api: "no",
            alerts: "no"
        }
    };

    axios.request(options).then((response) => {
        res.json(response.data);
    }).catch((error) => {
        console.log(error);
    });
});

app.listen(PORT, () => console.log(`Server running on PORT ${PORT} `))
 

Apologies if the message itself is convoluted. Any help/tips/comments are much appreciated!

javascript

reactjs

express

react-fullstack

0 Answers

Your Answer

Accepted video resources