Javascript - Using promise for post PHP, get undefined result - javascript

I'm a newbie in JS and have a little to no knowledge about asynchronous program and promise. I have a problem in getting result from post PHP as written in this code:
showModalLink = function(d, i) {
$('#myModalLabel').text(d.source.name + ' - ' + d.target.name);
$('#modalJum').text(d.jumlahlelangsama);
var lelang = d.daftarlelangsama.split(", ");
var lelangmodal = [];
var promises = [];
for (var i = 0; i < lelang.length; i++) {
querystring = "select pemenang from lelang where id = " + lelang[i];
console.log(querystring);
var queryobj = {
query: querystring
};
promises.push($.post('indikasi3modal.php', queryobj));
}
Promise.all(promises).then(function(results) {
if (results[i] == d.source.name) {
console.log("1");
lelangmodal.push(lelang[i] + " - dimenangkan oleh " + d.source.name);
console.log(lelangmodal);
}
else if (results[i] == d.target.name) {
console.log("2");
lelangmodal.push(lelang[i] + " - dimenangkan oleh " + d.target.name);
console.log(lelangmodal);
}
else {
console.log("3");
lelangmodal.push(lelang[i]);
console.log(lelangmodal);
}
$('#modalLelang').text(lelangmodal);
$('#myModal').modal('show');
});}
I have no idea why the results[i] return undefined inside then function loop. Any help (or alternative ways to solve this) appreciated. Thanks!

I have no idea why the results[i] return undefined inside then function loop.
Because you don't have a loop in the .then() function. So i has the value it had at the end of the loop that created all the promises, which is the number of promises that were created. But the indexes of results go from 0 to i-1.
Promise.all(promises).then(function(results) {
for (var i = 0; i < results.length; i++) {
if (results[i] == d.source.name) {
console.log("1");
lelangmodal.push(lelang[i] + " - dimenangkan oleh " + d.source.name);
console.log(lelangmodal);
} else if (results[i] == d.target.name) {
console.log("2");
lelangmodal.push(lelang[i] + " - dimenangkan oleh " + d.target.name);
console.log(lelangmodal);
} else {
console.log("3");
lelangmodal.push(lelang[i]);
console.log(lelangmodal);
}
}
$('#modalLelang').text(lelangmodal);
$('#myModal').modal('show');
});

Related

Filter data obtained through GitHub API

I created this function to obtain GitHub issues:
retrieveEnerpriseIssues: function(repoOrg, repoName, callback) {
let data = null;
// token auth
octokit.authenticate({
type: 'basic',
username: config.githubEnterprise.username,
password: config.githubEnterprise.token
});
async function paginate(method) {
let response = await method({
q: "repo:" + repoOrg + "/" + repoName + " is:issue",
per_page: 100
});
data = response.data.items;
var count = 0;
while (octokit.hasNextPage(response)) {
count++;
console.log(`request n°${count}`);
response = await octokit.getNextPage(response);
data = data.concat(response.data.items);
}
return data;
}
paginate(octokit.search.issues)
.then(data => {
callback(data);
})
.catch(error => {
console.log(error);
});
}
It is called in this function which takes the issues, filters out all of the unwanted keys into json format and puts it in my db.
extractToDb: function() {
let gitIssues = null;
for(var i = 0; i < config.githubEnterprise.orgs.length; i++) {
for(var j = 0; j < config.githubEnterprise.orgs[i].repos.length; j++) {
gitHubService.retrieveEnerpriseIssues(
config.githubEnterprise.orgs[i].owner,
config.githubEnterprise.orgs[i].repos[j].repoName,
function(data, err) {
if(err) {
console.log('err: ', err);
} else {
gitIssues = data;
}
gitIssues = JSON.stringify(gitIssues);
gitIssues = JSON.parse(gitIssues);
let issueFormatForDb = null;
for(var i = 0; i < gitIssues.length; i++) {
issueFormatForDb = gitIssues[i];
const body = '{' +
'"github_id": "' + issueFormatForDb.id + '",' +
'"issue_title": "' + issueFormatForDb.title + '",' +
'"issue_number": "' + issueFormatForDb.number + '",' +
'"issue_url": "' + issueFormatForDb.url + '",' +
'"issue_state": "' + issueFormatForDb.state + '"' +
'}';
console.log('Body: ', body);
getGitHubIssues.postToDb(body);
}
});
}
}
}
I'd like to take this a step further by filtering out any issues where the state is closed. How is this done and should it be handled in my retrieveEnerpriseIssues function or my extractToDb?
Possible solution
I tried this in my extractToDb function:
gitIssues = JSON.parse(gitIssues);
gitIssues = _.where(gitIssues, {state: "open"});
let issueFormatForDb = null;
Is it the best solution or is there a better way?
As #givehug stated:
Better use _.filter, or native filter method like
gitIssues = gitIssues.filter(i => i.state === 'open')
I think .where was deprecated in later versions of lodash github.com/lodash/lodash/wiki/Deprecations. Other than that its perfectly fine.
I just realsied I can filter the state in my paginate function with this:
let response = await method({
q: "repo:" + repoOrg + "/" + repoName + " is:issue" + " label:issue_label" + " state:open",
per_page: 100
});

Second loop is not working

I´m running this test with nightwatch and I have a loop inside a loop, first one runs ok but it fails going inside 2nd loop.
I wrote a console.log and returns:
Number of links:[object Object]
This is my code:
What´s the reason for not entering in loop 2?
Thanks in advance.
.execute(
function() {
return document.querySelectorAll('.menuElementsAgregator>li').length
},
function(result) {
total_links = result.value;
console.log("Number of main links:" + total_links);
for (var i = 2; i <= total_links; i++) {
(function (i) {
browser.waitForElementPresent('.menuElementsAgregator', 3000)
.click('.menuElementsAgregator>li:nth-child(' + i + ')>a')
.waitForElementVisible('.menuElementsAgregator>li:nth-child(' + i + ')', 2000)
.execute(
function () {
return document.querySelectorAll('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level .has-sub .clickableTabWithLink').length
},
function(result) {
total_links2 = result.value;
console.log("Number of links:" + total_links2);
for (var j = 2; j <= total_links2 + 1; j++) {
browser.waitUntilElementIsClickable('.menuElementsAgregator>li:nth-child(' + i + ')')
.click('.menuElementsAgregator>li:nth-child(' + i + ')')
.waitForElementPresent('.menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level>li:nth-of-type(' + j + ').has-sub', 5000)
.click(' .menuElementsAgregator>li:nth-of-type(' + i + ')>.tsr-nav-second-level>li:nth-of-type(' + j + ').has-sub .clickableTabWithLink:first-child')
.pause(1000)
.waitForElementVisible('.games-list', 5000);
}
}
)
})(i);
}
})
The problem is that total_links is not an integer but an object.
Try to replace
console.log("Number of main links:"+ total_links);
with
console.log("Number of main links:", total_links);
That will show you what's inside total_links. If you can't fix it add a comment with the content of total_links
Absolutely this code would not work, because you cant use a callback in a loop like that,your index 'i' in second loop would be equal 'total_links.length' all the time. You can try this:
.execute(
function() {
return document.querySelectorAll('.menuElementsAgregator>li').length
},
function(result) {
total_links = result.value;
console.log("Number of main links:" + total_links);
for (var i = 2; i <= total_links; i++) {
(function(i){ // this is a closure
browser.waitForElementPresent('.menuElementsAgregator', 3000)
.click('.menuElementsAgregator>li:nth-child(' + i + ')>a')
.waitForElementVisible('.menuElementsAgregator>li:nth-child(' + i + ')', 2000)
.execute(
function() {
return document.querySelectorAll('.menuElementsAgregator>li:nth-child(' + i + ')>.tsr-nav-second-level>.has-sub').length
},
function(result2) {
total_links2 = result2.value;
console.log("Number of links:" + total_links2);
for (var j = 0; j <= total_links2; j++) {// i = total_link.length already, before get in to this loop.
browser.waitForElementPresent('.menuElementsAgregator>li:nth-child(' + i + ')>.tsr-nav-second-level>.has-sub:nth(' + j + ')', 3000)
.click('.menuElementsAgregator>li:nth-child(' + i + ')>.tsr-nav-second-level>.has-sub:nth(' + j + ')>a')
.pause(3000)
.waitForElementVisible('.games-list', 5000);
}
}
)
})(i) // close
}
}
)
You should take a look at api .perform() , this will be help a a lot for this kind of work. It made my code cleaner and readable.
Ps: Spend some time to research closure.

Javascript unable to get control out of method

I have few problems with below code.Can anyone help?
The if (currentStatus!="undefined") block in getStatusUsingAjax methid is not working.
unable to get the control out of getStatusUsingAjax method
$(document).ready(
loadStatus()
);
function loadStatus(x) {
$('.a-IRR-table tr').each(function(i) {
var val = $(this).find("td").eq(0).text();
link = $(this).find("td").eq(0).find("a").attr("href");
linkTag = $(this).find("td").eq(0).find("a");
`if ((val !== "-") && (val !== "")) {
console.log("val is" + val);
if (verifyrequestArray(val)) {
console.log("inside second if");
} else {
console.log("inside else");
sleep(1.5 * 1000);
var updatedStatus2 = getStatusUsingAjax(val, link);
console.log("UpdatedStatus2 is " + updatedStatus2);
setTooltip(linkTag, updatedStatus2);
}
}
});
}
function verifyrequestArray(id) {
var newArray = requestArray.toString().split('-');
console.log("NewArray is :" + newArray);
for (i = 0; i < newArray.length; i++) {
// I'm looking for the index i, when the condition is true
if (newArray[i] === id) {
console.log("request id found" + newArray[i]);
break;
} else {
console.log("request id not found" + newArray[i]);
return false;
}
}
}
function getStatusUsingAjax(requestValue, currentlink) {
console.log("patch req: " + requestValue);
console.log("Link is " + currentlink);
var currentStatus;
GM_xmlhttpRequest({
method: "GET",
url: currentlink,
onload: function(response) {
if ($(response.responseText).find("#P16_STATUS2").size() === 1) {
currentStatus = $(response.responseText).find("#P16_STATUS2").text();
console.log("Current Status from #P16_STATUS2 is :" + currentStatus);
console.log("Final URL is " + response.finalUrl);
}
}
});
// console.log("Final URL is " +response.finalUrl);
if (currentStatus != "undefined") {
var pusharr = [requestValue + "-" + currentStatus];
requestArray.push(pusharr);
console.log("Updated Array is " + requestArray);
return currentStatus;
}
}
function setTooltip(currentTag, status2) {
console.log("in settooltip" + currentTag);
currentTag.attr("title", status2); //setting status a tooltip
}
Any clue where the error is?
fn getStatusUsingAjax is async, you can not get return value using:
var updatedStatus2 = getStatusUsingAjax(val, link);
You sholud create callback:
function getStatusUsingAjax(val, link, callback){
//...
// do not use return currentStatus, call calback fn instead
callback(currentStatus)
}
and call it using:
getStatusUsingAjax(val, link, function(updatedStatus2){
console.log("UpdatedStatus2 is " + updatedStatus2);
setTooltip(linkTag, updatedStatus2);
});

Constraint-less Parse query returns blank objects

I've usually been making queries to a class for a single, directed object using the objectId and it's all been working smoothly. However I am now trying to get all of the objects in a given class.
var values;
var Class = Parse.Object.extend(className);
var query = new Parse.Query(Class);
console.log(objectID);
if (typeof objectID !== "undefined") { //if the user specified objectID
query.get(objectID, {
success: function(retrieveObject) {
for (var i = 0; i < keys.length; i++) {
values[i] = query.get(keys[i]);
}
},
error: function(error) {
console.log("Failed to retrieve " + className + ': ' + error.message);
}
});
} else { //if not return all
query.limit(1000);
query.exists("objectId");
query.find({
success: function(results) {
console.log("the results are " + results);
for (var i = 0; i < results.length; i++) {
for (var j = 0; j < keys.length;j ++)
console.log("key " + j + " is " + keys[j]);
console.log("the result for " + j + " is " + results[i]);
var object = results[i];
values[i][j] = object.get(keys[j]);
console.log("the value for the key in result is " + values[i][j]);
}
},
error: function(error) {
console.log("Failed to retrieve " + className + ': ' + error.message);
}
});
}
For the life of me I cannot figure out why this does not work. "results" comes out as an array of the correct number of values, but each is "[object Object]"
Any ideas?

Unit testing a function and simulating an event emitter response

I am currently writing some tests against the code shown below in node.js using mocha. I want to simulate the response from the event emitter 'check_user'. I have sinon.js but I can't get my mind in the right place to work out the best way to simulate the response.
Anyone able to offer some advice on how to go about this?
TgCustomCommand.contact = new Command("contact", "Will send you a users contact card to add to your contact list. Usage is .contact nick", function (input, callback) {
var payload = input;
//Switch our contact to payload.to as this is what our checkuser function looks at
//Check the command over
if (payload.command_args === false) {
payload.response = 'msg ' + payload.to + ' ' + this.description;
return callback(null, payload);
} else {
payload.return = payload.to;
payload.to = payload.command_args; //Set up ready for nick check
//Check the nick exists
emitter.emit('check_user', payload, function (err, result) {
if (err) return callback(err, null);
payload = input; //Reset our payload so we have correct payload.to
//Check how many users we returned
if (result.length === 0) { //Not in our contact list
payload.response = 'msg ' + payload.return + ' I do not have that person in my contact list!';
return callback(null, payload);
} else if (result.length === 1) {
payload.to = result[0].Nick;
payload.response = "send_contact " + payload.return + ' ' + result[0].Phone + ' ' + result[0].Nick + " _";
return callback(null, payload);
}
else {
//loop through our object and create a list of those returned
payload.response = "msg " + payload.return + " I know multiple people with a similar nick: ";
for (var i = 0; i < result.length; i++) {
log.debug(result[i].Nick);
payload.response = payload.response + result[i].Nick + " ";
}
return callback(null, payload);
}
});
}
;
});

Categories