Search code examples
reactjsreduxreact-reduxreact-routerredux-thunk

How to pass input value as paremeter in the API call?


How to pass input value as paremeter in the API call. I want this app to perform like when you place the city name in the input field and then enter submit button to get all weather data. I checked weather data is coming and staying the state. but I dont know how to get the input CITY NAME AND PASS AS PAREMETER. I will appreciate it if you could help me.

//Action Creator ..

import weatherAPI from "../apis/weatherAPI";

export const fetchWeather = cityName => async dispatch => {
  const API_KEY = "240ef553958220e0d857212bc790cd14";

  const response = await weatherAPI.get(
    `/data/2.5/weather?q=${cityName}&appid=${API_KEY}`
  );
  dispatch({
    type: "FETCH_WEATHERLIST",
    payload: response.data
  });
};


//Reducer..
export default (state = [], action) => {
  if (action.type === "FETCH_WEATHERLIST") {
    return action.payload;
  }
  return {
    ...state
  };
};

//CombineRducer file..
import { combineReducers } from "redux";
import weatherListReducer from "./weatherListReducer";

export const rootReducer = combineReducers({
  weatherList: weatherListReducer
});
import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchWeather } from "../actions";
class SearchBar extends Component {
  componentDidMount() {
    this.props.fetchWeather();
  }

  onChangeHandler(e) {}
  onSubmitHandler(e) {
    e.preventDefault();
  }
  render() {
    console.log(this.props.list.main);

    return (
      <div className="row container">
        <h4 className="blue-text">Weather App</h4>
        <form className="col s12" onSubmit={this.onSubmitHandler}>
          <div className="input-field">
            <input type="text" id="searchbar" />
            <label htmlFor="searchbar">Search City For Weather Forecast</label>
          </div>
          <div className="input-field ">
            <button className="btn " onChange={this.onChangeHandler}>
              Search City
            </button>
          </div>
        </form>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    list: state.weatherList
  };
};

export default connect(mapStateToProps, { fetchWeather })(SearchBar);

Solution

  • so you need to access the input value so that pass it to the API. you have two ways to do that

    solution 1

    in this solution you need to create a local state to hold the input value and access that value from the state when submission. so you need to define state. assign changeHandler to the input and not the button.

    Note: this solution will cause component rerender on every change, if you need to avoid that refer to second solution.

    class SearchBar extends Component {
      constructor(){
         super();
         this.state = { value : "" };
         this.onChangeHandler = this.onChangeHandler.bind(this);
         this.onSubmitHandler = this.onSubmitHandler.bind(this);
      }
    
      componentDidMount() {
        this.props.fetchWeather();
      }
    
      onChangeHandler(e){
        this.setState({
          value: e.target.value
        })
      }
    
      onSubmitHandler(e){
        e.preventDefault();
        let cityName = this.state.value;
        this.props.fetchWeather(cityName);
      }
      render() {
        // console.log(this.props.list.main);
    
        return (
          <div className="row container">
            <h4 className="blue-text">Weather App</h4>
            <form className="col s12" onSubmit={this.onSubmitHandler}>
              <div className="input-field">
                <input type="text" id="searchbar" onChange={this.onChangeHandler} value={this.state.value} />
                <label htmlFor="searchbar">Search City For Weather Forecast</label>
              </div>
              <div className="input-field ">
                <button className="btn " type="submit">
                  Search City
                </button>
              </div>
            </form>
          </div>
        );
      }
    }
    

    solution 2:

    you can access the input value via React refs assign a ref to the input and you can access it from submission handler.

    class SearchBars extends Component {
    
      componentDidMount() {
        // this.props.fetchWeather();
      }
    
      onSubmitHandler = (e) => {
        e.preventDefault();
        let cityName = this.searchInput.value;        
        // this.props.fetchWeather(cityName);
      }
      render() {
        // console.log(this.props.list.main);
    
        return (
          <div className="row container">
            <h4 className="blue-text">Weather App</h4>
            <form className="col s12" onSubmit={this.onSubmitHandler}>
              <div className="input-field">
                <input type="text" id="searchbar" ref={(searchInput) => { this.searchInput = searchInput }} />
                <label htmlFor="searchbar">Search City For Weather Forecast</label>
              </div>
              <div className="input-field ">
                <button className="btn " type="submit">
                  Search City
                </button>
              </div>
            </form>
          </div>
        );
      }
    }