3

I am trying to use the Bing Search Image API to search through an array of items that I have called names. I have used the documentation on https://learn.microsoft.com/en-us/azure/cognitive-services/bing-image-search/quickstarts/nodejs for getting started on sending a request for JSON parsing. I am able to receive the image URLs back when calling the names individually, however, when I run the bing_image_search function through a for loop, the console prints that it couldn't find image results and if it does find some of them, they are not returned in order that the bing_image_search function calls each name in. Below is the code to show what I have going now. Any help is appreciated.

  var imagesArr = [];
  let num_results = 1;
  var names = []; // assume already filled with names

  let response_handler = function (response) {
    let body = '';
    response.on('data', function (d) {
        body += d;
    });
    response.on('end', function () {
        let imageResults = JSON.parse(body);
          if (imageResults.value) {
            let imageLink = imageResults.value[0].thumbnailUrl;
            //console.log(`Image result count: ${imageResults.value.length}`);
            //imagesArr.push(imageLink);
            //console.log(imageLink);
            return imageLink;
          }
          else {
            console.log("Couldn't find image results!");
          }
        
          });
    response.on('error', function (e) {
        console.log('Error: ' + e.message);
    });
  
  };

  let bing_image_search = function (search) {
    console.log('Searching images for: ' + search);
    let request_params = {
          method : 'GET',
          hostname : host,
          path : path + '?q=' + encodeURIComponent(search) + '&count=' + num_results,
          headers : {
              'Ocp-Apim-Subscription-Key' : subscriptionKey,
          }
      };
  
      let req = https.request(request_params, response_handler);
      req.end();
    }

  for(index in names) {
    bing_image_search(names[index]);
  }

1 Answer 1

1
+50

You might want to consider wrapping the bing_image_search logic in a promise to make it easier to control the flow... See if something like the below helps you:

const { RateLimiter } = require("limiter");
const limiter = new RateLimiter({ tokensPerInterval: 3, interval: "second" });

var imagesArr = [];
let num_results = 1;
var names = []; // assume already filled with names

function bing_image_search(search) {
    return new Promise(async (resolve,reject)=>{
        const remainingMessages = await limiter.removeTokens(1);
        console.log('Searching images for: ' + search);
        let request_params = {
            method : 'GET',
            hostname : host,
            path : path + '?q=' + encodeURIComponent(search) + '&count=' + num_results,
            headers : {
              'Ocp-Apim-Subscription-Key' : subscriptionKey,
            }
        };
  
        let req = https.request(request_params, (response)=>{
            let body = '';
            response.on('data', function (d) {
                body += d;
            });
            response.on('end', function () {
                let imageResults = JSON.parse(body);
                if (imageResults.value) {
                    let imageLink = imageResults.value[0].thumbnailUrl;
                    //console.log(`Image result count: ${imageResults.value.length}`);
                    //imagesArr.push(imageLink);
                    //console.log(imageLink);
                    resolve(imageLink);
                }
                else {
                    resolve("Couldn't find image results!");
                }
            });
            response.on('error', function (e) {
                reject(e);
            });       
        });
      
        req.on('error', (e) => {
            reject(e);
        });
      
        req.end();
    })
}

(async()=>{
    let imgUrls = []
    for (const name of names){
        let imgurl = await bing_image_search(name)
        imgUrls.push(imgurl)
    }   
})()
Sign up to request clarification or add additional context in comments.

9 Comments

Hi Sully, thanks for your comment. I got the following syntax error when trying your code? Any advice on this? "let results = await Promise.all(names.map(bing_image_search)); SyntaxError: await is only valid in async function"
Sorry - you could've added a .then handler, or wrapped it in an IIFE (I updated the sample to show the IIFE)
Hi Sully, so your solution partially works. Every time I run it in pairs of 3 names at a time it works, however if I do more names than that, it doesn't find the images some of the times. I have around 200 names to go through so if you have any advice I would appreciate it.
If you're sure each of the 200 or so names should get a response, you might be hitting a rate limit on the API. Check the documentation to see if they limit requests to a certain number within a time frame... you'd then need to add something like p-limit or something like this: npmjs.com/package/limiter
Looks like they have a 3 transactions per second limit on the free one, which is probably what you're hitting... azure.microsoft.com/en-us/pricing/details/cognitive-services/… try incorporating limiter to get around that
|

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.