Search code examples
javascriptreactjscreate-react-appnode-request

React request lib dont work on componentDidMount


Im trying to scrap some data from web page and i did the following functional code. I need use it in my react app, but it doesn't work.

The first code (runs ok):

var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();

app.get('/scrape', function (req, res) {
    url = 'http://www.foo.com/';

    request(url, function (error, response, html) {
        if (!error) {
            var $ = cheerio.load(html);

            var title, release, rating;
            var json = { title: "", release: "", rating: "" };

            $('h2').filter(function () {
                var data = $(this);
                json.title = data.text();
            });

            $('#journalDescription').filter(function () {
                var data = $(this);
                json.release = data.text();
            });

            $('h3').filter(function () {
                var data = $(this);
                json.rating = data.text();
            });
        }
        fs.writeFile('output.json', JSON.stringify(json, null, 4), function (err) {
            console.log('File successfully written! - Check your project directory for the output.json file');
        })
        res.send('Check your console!')
    });
})

app.listen('8081')
exports = module.exports = app;

I modified it to the code below for use in App.js file:

var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');

export default function getDadosBasicosUFC() {
    let ufc = {
        url: "http://foo.com",
        titulo: "",
        edicao: "",
        descricao: "",
        sumario: {
            url: "",
            artigos: []
        },
        titulosArtigos:  [],
        autoresArtigos:  []

    }

    request(ufc.url, function (error, response, html) {
        if (!error) {
            var $ = cheerio.load(html);

            $('h2').filter(function () {
                var data = $(this);
                ufc.titulo = data.text();
            });

            $('#journalDescription').filter(function () {
                var data = $(this);
                ufc.descricao = data.text();
            });

            $('h3').filter(function () {
                var data = $(this);
                ufc.edicao = data.text();
            });

            $('.menu').filter(function () {
                var data = $(this);
                ufc.sumario.url = data.children().first().children().first().attr('href');
            });
        }
    });
    return ufc;
}

The App.js code where im trying to use the code:

import React, { Component } from 'react';
import getDadosBasicosUFC from './RevistasResource'

class App extends Component {

    constructor() {
        super();
        this.state = {
            ufc: null
        }
    }

    componentDidMount() {
        let ufcData = getDadosBasicosUFC();
        this.setState({ufc: ufcData});
        console.log(this.state.ufc);
    }
}
export default App;

The project was created using create-react-app. When i run it i got the following error:

TypeError: http.IncomingMessage is undefined
./node_modules/express/lib/request.js
node_modules/express/lib/request.js:31

  28 |  * @public
  29 |  */
  30 | 
> 31 | var req = Object.create(http.IncomingMessage.prototype)
  32 | 
  33 | /**
  34 |  * Module exports.

How could i fix my code to run in in the App.js? Thanks


Solution

  • as Evan Trimboli said in comments if request is async, try this.

    async componentDidMount() {
      let ufcData = await getDadosBasicosUFC();
      this.setState({ufc: ufcData});
      console.log(this.state.ufc);
    }
    

    This is working for me when using axios, i think it should work also when using request. But to use that in app u need to configure ES7 async/await or if using create-react-app it's already configured.

    And you also need to make getDadosBasicosUFC async method, to wait for result to come back.