Azurespot
Azurespot

Reputation: 3152

Trying to get API's Promise resolved using map()

UPDATE: Solved!

The only change needed was making the await of the API call to a return, then the map was returned with both image names and ids. Still trying to get the map converted to an array, but this question for this post is solved. Here's the new printout:

1 face detected from image Family1-Son1.jpg with ID 98091e1e-bc8d-4c93-a850-a115684a6e6e
Family1-Son1.jpg
1 face detected from image Family1-Dad3.jpg with ID f94360f5-feb3-4d14-816f-7d854fc0b34c
Family1-Dad3.jpg
[ { '0': 'F',
    '1': 'a',
    '2': 'm',
    '3': 'i',
    '4': 'l',
    '5': 'y',
    '6': '1',
    '7': '-',
    '8': 'D',
    '9': 'a',
    '10': 'd',
    '11': '3',
    '12': '.',
    '13': 'j',
    '14': 'p',
    '15': 'g',
    id: 'f94360f5-feb3-4d14-816f-7d854fc0b34c' },
  { '0': 'F',
    '1': 'a',
    '2': 'm',
    '3': 'i',
    '4': 'l',
    '5': 'y',
    '6': '1',
    '7': '-',
    '8': 'S',
    '9': 'o',
    '10': 'n',
    '11': '1',
    '12': '.',
    '13': 'j',
    '14': 'p',
    '15': 'g',
    id: '98091e1e-bc8d-4c93-a850-a115684a6e6e' } ]
[ <2 empty items> ]
[]

I've tried many different methods on here, can't get them to work. This one is the closest I came. I am trying to call an API but on each item in an array. I can't do this in a regular loop, so many reasons why not. So someone said use the array.map() function instead of a loop. I got this far:

const IMAGE_BASE_URL = 'https://csdx.blob.core.windows.net/resources/Face/Images/'
let sourceImageFileNames = ['Family1-Dad3.jpg', 'Family1-Son1.jpg']

// Detect faces in the source image array, then get their IDs
let sourcefaceMap = await Promise.all(sourceImageFileNames.map(async (imageName) => {
   // Returns a Promise<DetectedFace[]>
    await client.face.detectWithUrl(IMAGE_BASE_URL + imageName)
        .then((faces) => {
            console.log(`${faces.length} face detected from image ${imageName} with ID ${faces[0].faceId}`)
            let id = faces[0].faceId
            return { ...imageName, id } 
        }).catch((err) => {
            console.log(`No face detected in: ${sourceImageFileNames[0]}.`)
            throw err;
        })
}))

let values = Object.values(sourcefaceMap)
console.log(values)

// Create an array to store the source face IDs
var sourceFaceIds = new Array(sourceImageFileNames.length)
console.log(sourceFaceIds)
let ids = sourceFaceIds.filter((id)=> {
    return id != null;
})

console.log(ids)

The values seem to be there in when debugging, but then when I try to return the map, it prints out as undefined. Even though the map does do the job of looping to get each id (as seen in the top two print statements). Here is my printout:

VERIFY
1 face(s) detected from image Family1-Dad3.jpg with ID f94360f5-feb3-4d14-816f-7d854fc0b34c
1 face(s) detected from image Family1-Son1.jpg with ID 98091e1e-bc8d-4c93-a850-a115684a6e6e
[ undefined, undefined ]
[ <2 empty items> ]
[ <2 empty items> ]

Here is a screenshot of the id having value, when I hover over it in the return statement: enter image description here

Basically, I am trying to do an API call with URL images, then the API will associate an ID with each face in the image. I need the API call to return all those IDs. In this case, it's only 2 IDs. How do I do this? At the end of my code, I just need an array of those IDs. That's all. Thanks.

Upvotes: 0

Views: 63

Answers (2)

Bergi
Bergi

Reputation: 664484

Your map callback didn't return anything, it only waited. Use

const values = await Promise.all(sourceImageFileNames.map(imageName => {
    // now *really* returns a Promise<DetectedFace[]>
    return client.face.detectWithUrl(IMAGE_BASE_URL + imageName)
        .then(faces => {
            console.log(`${faces.length} face detected from image ${imageName} with ID ${faces[0].faceId}`)
            let id = faces[0].faceId
            return { imageName, id } 
        }).catch((err) => {
            console.log(`No face detected in: ${sourceImageFileNames[0]}.`)
            throw err;
        })
}));
console.log(values);

I'm also pretty certain that you didn't want to spread the imageName string into an object, and don't need to call Object.values on an array to get its values as an array.

Upvotes: 1

iAmADeveloper
iAmADeveloper

Reputation: 667

I think the problem you are facing here on line let id = response.faceId.

id is getting its value from response.faceId please do check that faceId property present in the response object. If it is present then code will work as you expected.

Upvotes: 0

Related Questions