0

I made get request to Serp api, but learned that it is not possible to directly make fetch to Serp from React application, so I created local server and wrote logic for it, then I tested it with Postman and everything is fine. Then I had problems with CORS, I(guess) fixed them, but now I receive rejected promise on response and can't get rid of this. It gives

Unexpected end of input

Here is my server:

const SerpApi = require('google-search-results-nodejs');
const search = new SerpApi.GoogleSearch("myApiKey");
const express = require('express');
const app = express();

var allowCrossDomain = function (req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}


app.get('/:id', function (req, res) {
    console.log("Made request");
    const searchText = req.params.id;

    const params = {
        q: searchText,
        tbm: "shop",
    };

    const callback = function (data) {
        const objects = [...data["shopping_results"]];
        console.log("call back worked");

        if (!objects) {
            console.log("ERROR 404");
            res.status(404).send();
        }

        res.status(200).send(objects);
    };

    // Show result as JSON
    search.json(params, callback);
});

app.use(allowCrossDomain);

app.listen(3001, function () {

    console.log("App is listening for queries");
})

and my fetch:

import updateOnSearchRequest from '../redux/actions/updateOnSearchRequest';

export default function searchRequestToApi(queryText, dispatch) {
    fetch(`http://localhost:3001/${queryText}`, {
        mode: 'no-cors',
    })
        .then(res => console.log(res.json()))
        .then(data => data ? dispatch(updateOnSearchRequest(data)) : {});
}

I receive error at console.log(res.json()) even though server works fine and doesnt give any errors

1 Answers1

0

First of all, you need to remove mode: "no-cors", as mentioned in this answer, using it will give you an opaque response, which doesn't seem to return data in the body.

Second, move your app.use(allowCrossDomain); to the top so it's higher than app.get("/:id", function (req, res) {....

And lastly, you must remove console.log from .then(res => console.log(res.json())).

In summary, your server should be:

const SerpApi = require("google-search-results-nodejs");
const search = new SerpApi.GoogleSearch("myApiKey");
const express = require("express");
const app = express();

var allowCrossDomain = function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  next();
};

app.use(allowCrossDomain);

app.get("/:id", function (req, res) {
  console.log("Made request");
  const searchText = req.params.id;

  const params = {
    q: searchText,
    tbm: "shop",
  };

  const callback = function (data) {
    const objects = [...data["shopping_results"]];
    console.log("call back worked");

    if (!objects) {
      console.log("ERROR 404");
      res.status(404).send();
    }

    res.status(200).send(objects);
  };

  // Show result as JSON
  search.json(params, callback);
});

app.listen(3001, function () {
  console.log("App is listening for queries");
});

And your fetch should be:

 fetch(`http://localhost:3001/${queryText}`)
        .then(res => res.json())
        .then(data => data ? dispatch(updateOnSearchRequest(data)) : {});
Mikhail Zub
  • 454
  • 3
  • 9