0

Good day, everybody! I have a small problem here with one of my React apps: I am trying to get the Weather alerts using an API. My App.js file looks like this:

import React, { Component } from 'react';
import './App.css';
import $ from 'jquery';
import Alerts from './Components/Alerts';

class App extends Component {

  constructor(){
    super();
    this.state = {
      alerts:[]
    }
  }

  getAlerts(){
    $.ajax({
      url: 'https://api.weather.gov/alerts/active/zone/AKZ201',
      dataType: 'json',
      cache: false,
      success: function(data){
        this.setState({alerts: data});
      }.bind(this),
      error: function(xhr, status, err){
        console.log(err);
      }
    });
  }


  componentDidMount(){
    this.getAlerts();
  }

  render() {
    return (
      <div>
        <Alerts alerts={this.state.alerts} />
      </div>
    );
  }
}

export default App;

The problem is that this ajax function is adding an extra parameter at the end of the API URL and because of this extra parameter the API URL doesn't return me the correct data.

This is what I get in my console:

jquery.js:9600 GET https://api.weather.gov/alerts/active/zone/AKZ201?_=1527798208757 400 ()

The extra parameter is ?_=1527798208757 400 ()

I figured it out that this extra parameter is causing the problem. Any ideas how I could remove this parameter?

Thank you!

Ritwick Dey
  • 18,464
  • 3
  • 24
  • 37
Victor Rusu
  • 107
  • 1
  • 1
  • 9
  • Remove the `cache: false`; it's adding a cachebusting param, no? – Dave Newton May 31 '18 at 20:39
  • You may need to bind `getAlerts` in your constructor because you're using `this` inside that function. Also, you need to bind your error per the example in the answer over here: https://stackoverflow.com/questions/29990809/handling-ajax-with-react – Jason Warta May 31 '18 at 20:41

3 Answers3

2

This is more of a jQuery question then a react one. As answered before, the extra timestamp is added because of your cache: false code. The Its a common way to cache bust a resource when its loaded, as appending a timestamp param forces the browser to fetch the latest resource.

Also, I don't know your reason for using jQuery in react, but at least for HTTP calls, you might want to look into Fetch API, a native browser api (no packages to install) compatible with modern browsers.

Here is a more modern example of your method when using fetch & ES2017

async getAlerts = () => {
  const response = await fetch('https://api.weather.gov/alerts/active/zone/AKZ201');
  const alerts = await response.json();

  this.setState({
    alerts,
  });
}

There are some cool ES2017 things going on here. First, is the inclusion of async/await, which really helps write easy to read asynchronous code. If you want a method/function to execute something asynchronously, you specify async as a prefix for that function/method.

async function() {}

We are also using the arrow function here getAlerts = () => {} to bind the getAlerts method to a function that maintains the same context of this. The payoff? If you wanted to use this in a jsx statement, you wouldn't have to .bind(this) or worry about what this is actually referencing.

<button onClick={this.getAlerts}>Update Alerts</button>

Next we want the results of our get request, and since its an asynchronous call to some database, we prepend our function call with await, to get the results of the underlying promise.

const response = await somePromise() //in our case, its fetch(url)

The response body can be gotten using response.json(), another asynchronous method call.

const alerts = await response.json();

The next bit, you notice we are using the name of the object as the an object key. saying {alerts} is the same as {alerts: alerts}, but your writing less code, and tis a little easier on the eyes!

this.setState({
  alerts,
});

Incase you don't have ES2017, (I was assuming that your using create-react-app, which includes these features enabled), here is an es6 version of that same method above:

getAlerts = () => {
  fetch('https://api.weather.gov/alerts/active/zone/AKZ201')
    .then((response) => response.json())
    .then((alerts) => {
      this.setState({
        alerts,
      });
    });
}
Mathew Kleppin
  • 302
  • 2
  • 7
1

The reason that the extra _=<timestamp> parameter is appended to the end of your request URL is because of the cache: false option you are specifying in your $.ajax call. It's one of the ways to ensure that you are receiving a non browser-cached version of the requested resource.

See the official docs.

Allen G
  • 438
  • 4
  • 6
0

Jquery appends _={timestamp} when you set cache: false.

$.ajax({
      url: 'https://api.weather.gov/alerts/active/zone/AKZ201',
      dataType: 'json',
      cache: true,
      success: function(data){
       console.log(JSON.stringify(data))
      },
      error: function(xhr, status, err){
        console.log(err);
      }
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Reference: Official Jquery Docs

Ritwick Dey
  • 18,464
  • 3
  • 24
  • 37