【问题标题】:Why I am not able to fetch query into my fetch url?为什么我无法将查询提取到我的提取 url?
【发布时间】:2020-01-17 15:07:40
【问题描述】:

我正在使用 2 个 API,从第一个开始,我提取纬度和经度,然后提取到我的第二个 API 参数中以获取天气 JSON 数据。

在表单部分,我使用了一个简单的文本输入来输入城市名称、一个日期选择器,我可以从中选择天气信息的日期和一个提交按钮。

有什么问题?

  1. 当我尝试动态获取查询到我的第二个 URL 时,由于某种原因它不起作用,但是当我尝试呈现相同的 this.state.lon 时,它会正确呈现我页面的经度。
  2. 以前,我认为这是因为我的状态对象没有更新,并且我调用了没有任何值的第二个 API,但事实并非如此。
  3. 我什至最后尝试调用 apicall1(),所以一切都从第一个开始,然后只有我可以调用第二个。但同样的问题。
  4. 第二个 API 收到错误请求,因为 lonlat 的查询参数为空
import React, { Component } from "react";
import DatePicker from "react-date-picker";

class Form extends Component {
  state = {
    inputCity: "",
    lat: "",
    lon: "",
    date: new Date(),
    condition: "",
    minimumTemperature: "",
    maximumTemperature: "",
    calendar: ""
  };

  apicall() {
    let API_KEY_OPEN_WEATHER = "my api";

    let city = this.state.inputCity;

    let corsCurrent = `http://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${API_KEY_OPEN_WEATHER}&units=metric`;

    fetch(corsCurrent)
      .then(results => {
        return results.json();
      })
      .then(data => {
        console.log(data);
        let lat = data.coord.lat;
        let lon = data.coord.lon;
        let condition = data.weather[0].main;
        let minimumTemperature = data.main.temp_min;
        let maximumTemperature = data.main.temp_max;
        this.setState({
          lat: lat,
          lon: lon,
          condition: condition,
          minimumTemperature: minimumTemperature,
          maximumTemperature: maximumTemperature
        });
      });
  }

  apicall1() {
    let API_KEY_OPEN_WEATHER = "my api";
    let API_KEY_DARKSKY = "my api";

    let city = this.state.inputCity;
    let lat = this.state.lat;
    let lon = this.state.lon;
    let unix = this.state.calendar;

    let corsCurrent = `http://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${API_KEY_OPEN_WEATHER}&units=metric`;
    let corsHistorical = `https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/${API_KEY_DARKSKY}/${lat},${lon},1579257722?exclude=currently,flags,minutely,hourly`;
    fetch(corsHistorical)
      .then(results1 => {
        return results1.json();
      })
      .then(data1 => console.log(data1));
  }

  onChange = date => {
    this.setState({ date });
    console.log("changed");
  };

  handleSubmit = e => {
    console.log("submit");
    e.preventDefault();

    this.apicall();

    let year = this.state.date.getFullYear();
    let month = this.state.date.getMonth() + 1;
    let date = this.state.date.getDate();

    let calendarr = year + "," + " " + month + "," + " " + date;
    this.setState({
      calendar: calendarr
    });
  };

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <input
            onChange={e => this.setState({ inputCity: e.target.value })}
            type="text"
            placeholder="Enter City Name"
            required
          />

          <button type="submit">Submit</button>
        </form>

        <DatePicker onChange={this.onChange} value={this.state.date} />

        <p>{this.state.lat}</p>
        <p>{this.state.lon}</p>
        <p>{this.state.condition}</p>
        <p>{this.state.minimumTemperature}</p>
        <p>{this.state.maximumTemperature}</p>
        <p>{new Date(this.state.calendar).getTime()}</p>
      </div>
    );
  }
}

export default Form;

【问题讨论】:

  • 我会隐藏你的 API 凭据
  • 同意。最好删除这个问题并再次询问没有键(任何人都可以看到编辑历史)。
  • @mbojko,下面还有更多 API 凭据 :-)
  • 你在哪里调用第二个 api 调用?无论如何,您的问题似乎与异步调用有关。尝试在你的 api 调用中使用 Promise 或回调,并记住 setState is an asyncronous method too,所以如果你在更新它们之后使用状态值,你应该使用它的回调。
  • 如果您需要代码方面的帮助,请告诉我。

标签: javascript json reactjs rest


【解决方案1】:

如果您想在第一个 API 调用之后调用第二个 API 调用,并且仅按此顺序,您需要 asynchronous 方法。

你可以使用asyncawait

创建异步函数并在其中使用 await 进行第一次调用,然后调用第二次。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

【讨论】:

    【解决方案2】:

    我注意到您缺少组件的构造函数。我还将 CORS 添加到您的 fetches 中,因为您的 API 请求将发送到另一个域。

    import React, { Component } from "react";
    import DatePicker from "react-date-picker";
    
    class Form extends Component {
      constructor(props) {
        super(props);
        this.state = {
          inputCity: "",
          lat: "",
          lon: "",
          date: new Date(),
          condition: "",
          minimumTemperature: "",
          maximumTemperature: "",
          calendar: ""
        };
      }
    
      apicall() {
        let API_KEY_OPEN_WEATHER = "my api";
    
        let city = this.state.inputCity;
    
        let corsCurrent = `http://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${API_KEY_OPEN_WEATHER}&units=metric`;
    
        fetch(corsCurrent, { mode: "cors" })
          .then(results => {
            return results.json();
          })
          .then(data => {
            console.log(data);
            let lat = data.coord.lat;
            let lon = data.coord.lon;
            let condition = data.weather[0].main;
            let minimumTemperature = data.main.temp_min;
            let maximumTemperature = data.main.temp_max;
            this.setState({
              lat: lat,
              lon: lon,
              condition: condition,
              minimumTemperature: minimumTemperature,
              maximumTemperature: maximumTemperature
            });
          });
      }
    
      apicall1() {
        let API_KEY_OPEN_WEATHER = "my api";
        let API_KEY_DARKSKY = "my api";
    
        let city = this.state.inputCity;
        let lat = this.state.lat;
        let lon = this.state.lon;
        let unix = this.state.calendar;
    
        let corsCurrent = `http://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${API_KEY_OPEN_WEATHER}&units=metric`;
        let corsHistorical = `https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/${API_KEY_DARKSKY}/${lat},${lon},1579257722?exclude=currently,flags,minutely,hourly`;
        fetch(corsHistorical, { mode: "cors" })
          .then(results1 => {
            return results1.json();
          })
          .then(data1 => console.log(data1));
      }
    
      onChange = date => {
        this.setState({ date });
        console.log("changed");
      };
    
      handleSubmit = e => {
        console.log("submit");
        e.preventDefault();
    
        this.apicall();
    
        let year = this.state.date.getFullYear();
        let month = this.state.date.getMonth() + 1;
        let date = this.state.date.getDate();
    
        let calendarr = year + "," + " " + month + "," + " " + date;
        this.setState({
          calendar: calendarr
        });
      };
    
      render() {
        return (
          <div>
            <form onSubmit={this.handleSubmit}>
              <input
                onChange={e => this.setState({ inputCity: e.target.value })}
                type="text"
                placeholder="Enter City Name"
                required
              />
    
              <button type="submit">Submit</button>
            </form>
    
            <DatePicker onChange={this.onChange} value={this.state.date} />
    
            <p>{this.state.lat}</p>
            <p>{this.state.lon}</p>
            <p>{this.state.condition}</p>
            <p>{this.state.minimumTemperature}</p>
            <p>{this.state.maximumTemperature}</p>
            <p>{new Date(this.state.calendar).getTime()}</p>
          </div>
        );
      }
    }
    
    export default Form;
    

    【讨论】:

    • 我绑定了这个,仍然得到同样的错误,“格式错误的请求”。我无法将 lat 和 lon 传递给我的查询
    • 我修复了 CORS 问题。我无法测试 API 凭据,但请求一直通过,直到到达 data.coord.lat
    猜你喜欢
    • 2019-12-26
    • 2016-05-25
    • 2021-09-09
    • 2016-10-13
    • 1970-01-01
    • 2021-01-17
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多