8

Im trying to display any data from an ajax request, done inside react.js. so far no joy....

its trying to pull data from a test web API, JQuery is installed, although not necessary, i have looked at alternatives, but struggled so far to implement them.

For the request i am trying two things, to bind the data by this and with an append method from Jquery, both don't work. Everything else renders and the console is not spitting out any errors.

I am trying to work towards a generic function that can easily be ported over for react-native, but im stuck even at this JQuery implementation.

var url = 'https://demo2697834.mockable.io/movies';

//main logic
var GetStuff= React.createClass({

    getInitialState: function() {
      return {
        entries: []
      };
    },

    componentDidMount: function() {
        $.ajax({
          url: 'https://demo2697834.mockable.io/movies',
          dataType: 'json',
          cache: false,
          success: function(data) {
            this.setState({entries: data});
            $('.test').append(data);
          }.bind(this),
          error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
          }.bind(this)
        });
      },

    render: function() {
      return (
        <div>{this.state.entries}</div>
      );
    }
});

//markup
<body style={MainStyles.alldivs}>
    <Header />
    <GetStuff/>
    <div class='test'></div>
    {this.props.children}
    <Footer />
</body>

Update 1

so i changed the properties to fit the entries declaration. No change, and i tried to pass in the props URL parameter, but no change either. I have also removed the old school JQuery append, im 100% trying to get on board with react, shame its not an easy segway transition.

Do i need to change anything in the server config? i am using express?

Update 2

It' seems the componentDidMount function is not calling at all, to save confusion i will post my full code.

import React from 'react';
import ReactDom from 'react-dom';
import $ from "min-jquery";
import Header from './header';
import Footer from './footer';
//AJAX request
var GetStuff= React.createClass({
    getInitialState: function() {
      return {
        entries: []
      };
    },
    componentDidMount: function() {
        $.ajax({
          url: 'https://demo2697834.mockable.io/movies',
          dataType: 'json',
          cache: false,
          success: function(data) {
            this.setState({entries: data});
            console.log('success');
          }.bind(this),
          error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
            console.log('fail');
          }.bind(this)
        });
      },
    render: function() {
      return (
        <div> HERE: 
          {this.state.entries}
        </div>
      );
    }
});


// Stylesheet stuff is here, not important for this post.

//Render
var MasterLayout = React.createClass({ 
    render: function(){
        return(
            <html lang="en">
            <head>
                <title>{this.props.name}</title>
            </head>
            <body style={MainStyles.alldivs}>
                <Header />
                <GetStuff />
                {this.props.children}
                <Footer />
            </body>
            </html>
        )   
    }
});


// no idea if this is the correct setup, again docs are lacking on the real use of this.

    if(typeof window !== 'undefined') {
        ReactDom.reder(<MasterLayout />, document.getElementByID("content"));
    }
    module.exports = MasterLayout;
5
  • 1
    In your AJAX callbacks and in your render method, you reference this.state.data, but in getInitialState you start state with entries, not data. Use this.setState({entries: data}); in your success callback and call this.state.entries in your render. Commented Apr 22, 2016 at 1:57
  • 2
    Also, you aren't thinking in React world. There is no place in React for $('.test').append(data);. You should never manually change the DOM. Remove the test div and just use the render that you have in GetStuff Commented Apr 22, 2016 at 1:59
  • @MatthewHerbst I see the logic, still a steep learning curve, the docs seem to jump stages a bit. Thank you for the help so far. Will try to do everything in react and get on board with its logic. Commented Apr 22, 2016 at 2:35
  • where is your ReactDOM.render function....? Commented Apr 22, 2016 at 2:36
  • @JordanHendrix I don't call it anywhere in my app, i was under the impression the routes functionality offered by express would solve this. Commented Apr 22, 2016 at 2:52

2 Answers 2

4

Well from what I can see is that you're not loading any URL, take this:

url: this.props.url,

You've not assigned any props called url. You've only assigned a variable named url at the top of your file.

So what you can do is add something along the lines of this:

<GetStuff url="https://demo2697834.mockable.io/movies" />

Also I noticed you want to port this function over to react-native. I wouldn't use ajax for that. Look into the fetch method...It's much the same as ajax and it's what react native uses by default. https://facebook.github.io/react-native/docs/network.html

Your request would look something like this:

fetch(this.props.url, {
  method: 'GET',
  headers: {
    'Accept': 'application/json',
  },
}).then (function (response) {return response.json()})
  .then(function (json) {/* Here is your json */})
  .catch(function (error) {/*Handle error*/});

Edit:

Hmmm...it seems like you aren't able to access the props. Try console.log this.props inside your componentWillMount. But I think I know the reasoning behind this.props.url not working inside your ajax function.

this. inside the ajax function refers to the ajax this, and not the react this.

What you could do is bind this to your ajax function or assign this.props.url to a variable outside the ajax function (this is what I would do). Examples:

componentDidMount: function() {
        var url = this.props.url;
        $.ajax({
            url: url,

BTW, checkout this question for more details: React tutorial- why binding this in ajax call

Edit 2:

I noticed you're using plain react with no typescript or architecture such as redux. I suggest you look into using babel with es6 and redux (it handles everything to do with the apps state, it's a must! It's a flux implementation).

I haven't used plain react in a while and you might have to set propTypes and then assign the props in your getInitialState function.

propTypes: {
    url: React.PropTypes.string,
},
getInitialState: function() {
    return {
        url: this.props.url,
    };
}

You can then go and access the url value using this.state.url.

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

3 Comments

Thanks for the heads up on the fetch. Tried to use the props declaration, but no joy, to eliminate the errors for now, i just changed it to url:'demo2697834.mockable.io/movies'
@Paddy - CHeck my update...I believe I've found the cause. this inside the ajax function is referring to the ajax this object and not the react one.
yea changed, but no joy. Its something so small i know it, one of those fidley config things. I have to say i'm a bit surprised react does it this way, can't see why they re-invent a wheel and make it harder.
0

This is my working sample code. Please refer to the syntax correctly in .bind(this) which is incorrect in your code.

<div id="element"></div>
<script type="text/jsx">

 var JavaEEWSTest = React.createClass({
                getInitialState: function () {
                    return {text: ''};
                },
                componentDidMount: function(){
                    $.ajax({
                        url: "http://localhost:8080/RestWeb/rest/city"
                    }).then(function(data) {
                        console.log(data.City.city);
                        this.setState({text: data.City.city});
                    }.bind(this))
                },
                render: function() {
                    return <div>Response - {this.state.text}</div>;
                }
            });

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.