K.Takahashi
K.Takahashi

Reputation: 13

About Promise Then

I wrote the following code to POST a mentioned message to Slack.

const resultSlack = [];
const selectedItems2 = 'XX : TESTS';

const getUserid = (value) => {
    return new Promise(resolve => {
    for (let i = 0; i < value.length; i++) {
        let str = value[i].slice(5);
        let body = {
            app: XXX,
            query: '"'+ str +'"'
        };
        kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body, resp => {
            resultSlack.push("<@" + resp.records[0].slackId.value + ">");
        });
    }
    resolve(resultSlack);
    });
};
getUserid(selectedItems2).then(results => {
    console.log(results);
    //There is an array
    //0: "<@XXXXXXXX>"
    //1: "<@YYYYYYYY>"
    //2: "<@ZZZZZZZZ>"
    //3: "<@SSSSSSSS>"
    const payload = { text: results + "send already" }; 
    //specify results in the payload, it will be ignored.
    console.log(payload); // text: "send already"
});

Is it not possible to access the array passed as an argument with the then method? How can I use the values ​​in the array in results? Please give me some advice.

Upvotes: 1

Views: 214

Answers (3)

Nezih
Nezih

Reputation: 379

const getUserid = (value) => {
return new Promise(async resolve => {
for (let i = 0; i < value.length; i++) {
    let str = value[i].slice(5);
    let body = {
        app: XXX,
        query: '"'+ str +'"'
    };
    await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body, resp => {
        resultSlack.push("<@" + resp.records[0].slackId.value + ">");
    });
}
resolve(resultSlack);
});
};

When you calling an async function that makes a http request, you need to use await to wait until process done.

Upvotes: 0

Titus
Titus

Reputation: 22474

You have to wait for the responses to all the API calls to come in before resolving the promise.

A better way of doing this will be to transform the API calls into promises and resolve them all, here is an example:

const getUserid = (value) => {
    const requests = [];
    for (let i = 0; i < value.length; i++) {
        let str = value[i].slice(5);
        requests.push({
            app: XXX,
            query: '"'+ str +'"'
        });
        
    }
    return Promise.all(requests.map((req) => new Promise(resolve => kintone.api(kintone.api.url('/k/v1/records', true), 'GET', req, resp => {
            resolve("<@" + resp.records[0].slackId.value + ">");
        })));
};

Upvotes: 1

TKoL
TKoL

Reputation: 13892

Your code isn't right because it isn't properly waiting for the results from kintone.api() in your loop.

Fortunately for you, kintone.api() actually has the possiblity to return a promise! https://developer.kintone.io/hc/en-us/articles/212494388/

That means you can use async/await syntax inside your loop:

const getUserid = async (value) => {
    const resultSlack = [];
    for (let i = 0; i < value.length; i++) {
        let str = value[i].slice(5);
        let body = {
            app: XXX,
            query: '"'+ str +'"'
        };
        const resp = await kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body);
        resultSlack.push("<@" + resp.records[0].slackId.value + ">");
    }
    return resultSlack;
};

(warning: that code DOESN'T make all the looped requests simultaneously, which is possible if you feel you need it. It makes each request one at a time as written)

Now that that's written as an async function, you can do this:

getUserid(selectedItems2).then(results => ...

Upvotes: 3

Related Questions