Image Abstraction Layer - using native node http.get method

Image Abstraction Layer - using native node http.get method
0

#1

I’m trying to figure out how to manipulate the response body returned from Google CSE API. I want to use the native http module as I want to understand how I can use it. I’m not opposed to modules, I just rather use the native one if I can get it working. Thanks in advance.

Here is my code:

const express = require('express');
const app = express();
const https = require('https');
// const bodyParser = require('body-parser');
const port = process.env.PORT || 3000;

const ENDPOINT='www.googleapis.com'
const PATH='/customsearch/v1';
const API_KEY='...';
const CUSTOM_SEARCH_ID='&cx=...';
const QUERY_PREFIX='&q=';

// app.use(bodyParser);

app.get('/:query', (req, res) => {
	if (req.params.length) {
		res.send(req.params.query);
	}

	const options = {
	  host: ENDPOINT,
	  path: `${PATH}${API_KEY}${CUSTOM_SEARCH_ID}${QUERY_PREFIX}${req.params.query}`,
	  prettyPrint: true,
	  searchType: 'image',
	  cr: 'countryUS',
	};

	const imageRequest = https.get(options, (response) => {
	 	let body=[];
 		response.setEncoding('utf8');

	  response.on('data', (data) => {
	  	body += data;
	  });
	  response.on('end', () => {
	  // want to get this to work	
          //const results = body.items.map((results, item) =>{
	  	//	return {
	  	//		url: item.link,
	  	//		snippet: item.title,
	  	//		thumbnail: item.pagemap.cse_thumbnail,
	  	//		context:item.formatted.url,
	  	//	};
	  	//}, []);
	 
	  	res.setHeader('Content-Type', 'application/json');
                // want to modify body here before sending it to the frontend
	  	res.send(body);
	  });
	}).on('error', (e)=> {
		console.log('Request error:', e.message);
	}).end();
});

app.listen(port, () => console.log(`Listening on port ${port}`));

#2

I don’t think your arguments to the map function are correct. map function
Shouldn’t item be the first parameter? body.items.map( (item) => { ... })


#3

hi @nikrb, thanks for the reply. you are correct that my map syntax is wrong, this is for reduce instead. which i previously tried to use. that isn’t my problem though. i’m trying to manipulate the response after it has been received but I can’t. Any advice?


#4

sorry to ask possibly a silly question, but why can’t you manipulate it? are you getting errors or … ?


#5

When i try to access a prop in the response body ex. Body.images…says cant find images of undefined.


#6

please bear in mind this is all new to me too.
in response.on( 'data', (data) => { body += data; }); print out data, e.g. console.log( data); and see what you have.


#7

That works but my goal is to manipulate the data before i send it to the browser. I want to send back a format array of objects to match the pattern given in the example.


#8

what I’m trying to get at is the structure of the data returned. If it is an array, then body.images won’t be defined. If you think about body += data, this just appends the data array to the body array. IF it is an array, then body.map is what you want, not body.images. same applies for .reduce
hope this helps


#9

body isn’t an array. The response I was expecting had an array of images. At any rate, moot point now since I’ve solved the issue. My problem from the original post was that I wasn’t using an add’l callback to handle my data.

Below I need to call returnData to be able to manipulate my data

 response.on('end', function() {
      const items = returnData(body);
      res.send(items);
    });

and here is the code for returnData function

function returnData(data) {
  body = JSON.parse(data);
    const items = body.items.map((item) => {
    return ({
      url: getImage(item),
      snippet: item.title,
      thumbnail: getThumbnail(item),
      context:item.formattedUrl,
    });
  });

  return items;
}

Again thanks for taking the time to help.


#10

great stuff, feels good doesn’t it :smile: