While running webdriver IO codes returning Object Promises - async-await

get verifyText(){
return $(".uU7dJb");
}
async loadText(){
var Elem;
Elem = (await this.verifyText).getText();
console.log(" " +Elem);
}
**running above code not returning Element text instead it returning " [object Promise]" **

Related

For loop in promise function

I have below functions that I am trying to use an async function to check if an item Id was already added into a grid. But, I am stuck at the for loop "processFindCode" function, it always returns false. How to make the checking routine work and continue to addItem function?
My objective,
1. a loop up event pass in selected array values
2. get needed info array via web api
3. process each of array item
4. validate if the item.Id_item_code already exists in detail grid, if not add a new item into the grid
sorry for the lengthy code, I am considered new to js. please also advise the best way to achieve my objective.
Thank in advance
var theList = this.value;
if (theList == "") {
return true;
}
// Set up aysnc promise function
async function processAPIResult() {
let result;
let promises = []; //setup a promises aray
// Loop thru Lookup selections
// results store in the promises aray
theList.split(',').forEach(function (kId, k) {
promises.push(make_api_call(kId));
})
result = await Promise.all(promises); // async await
return result;
}
// Call API Function
function make_api_call(id) {
return ($.get(ew.API_URL + "GetQuotationDetail/" + encodeURIComponent(id)));
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 300));
}
async function addItem(kcode) {
var ridx = $("#key_count_fs_invoicedtlgrid")[0].value; // get actual table row
// Get serices information from API
var tQty = 1;
if (ridx == 1 && $("#x1_Id_item_code")[0].value == "") {
$("#x" + ridx + "_Id_item_code").value(kcode);
$("#x" + ridx + "_qty").value(tQty);
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
} else {
// 2nd row onward
// when it is available but it it is not empty, create a new row
if (typeof $("#x" + ridx + "_Id_item_code") === 'undefined' || $("#x" + ridx + "_Id_item_code")[0] != "") {
ew.addGridRow('#tbl_s_invoicedtlgrid');
}
ridx = $("#key_count_fs_invoicedtlgrid")[0].value;
var c_part_code = $("#x" + ridx + "_Id_item_code")[0];
var c_qty = $("#x" + ridx + "_qty")[0];
c_part_code.value = kcode;
c_qty.value = fmtDecimal(tQty, 'qty');
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
// trigger onChange to updateAmount() function;
$("#x" + ridx + "_qty").change();
}
}
async function processFindCode(code) {
found = false;
var rCnt = $("#key_count_fs_invoicedtlgrid")[0].value;
for (j = 1; j < rCnt + 1; j++) {
// loop thru row and col
if ($("#x" + j + "_item_code").val() != null) {
if ($("#x" + j + "_item_code").val() == kcode) {
if ($("#x" + j + "_item_code")[0].style.display != "none") { // visible row only. Deleted row's display is set to hidden.
found = true;
}
break; // exit loop column
}
}
if (found) {
break; // exit loop row
}
} // end for loop rCnt
isFound = found;
return isFound;
}
async function processItemCode(code) {
// notice that we can await a function
// that returns a promise
let isFound = await processFindCode(code);
await delay();
if (!isFound) {
await addItem(code);
}
console.log('Done! ' + code);
//await delay();
//console.log(item.Id_item_code);
}
async function processAPIitem(item) {
for (const itm of item) {
await processItemCode(itm.Id_item_code);
}
//console.log('Done! '+ apiitem.Id_item_code);
}
// main async task to get results
//-------------------------------
async function doTask() {
//get result form API function
let result = await processAPIResult();
//process each API array
for (const item of result) {
await processAPIitem([item]);
}
}
doTask();
Simple answer: $item_code.hide() hides; it isn't a test. Use $item_code.is(':visible') instead.
function processFindCode(code) {
var found = false;
var rCnt = $('#key_count_fs_invoicedtlgrid').val();
for (var j=1; j<rCnt+1; j++) {
if ($('#x' + j + '_item_code').val() != null) {
if ($('#x' + j + '_item_code').val() == code) {
if ($('#x' + j + '_item_code').is(':visible')) {
found = true;
break;
}
}
}
}
return found;
}
Longer answer: Finding the desired element with $('#x' + j + '_item_code') is inefficient especially when performed three times. You can improve matters by leveraging the power of javascript/jQuery and write something like this.
function processFindCode(code) {
var $rows = $('#tbl_s_invoicedtlgrid tbody tr'); // select all table rows in the table's tbody (assumed selector) .
return $rows.get().reduce(function(bool, row) {
return bool || $("id*='_item_code'", row).filter(':visible').filter(function() {
return this.value === code;
}).length > 0;
}, false);
}
This is still not as efficient as it could be. The "id*='_item_code'" selector is pretty nasty but at least it only applies to one row at a time, not the whole DOM.
For vastly improved efficiency, give the item_code element class="item_code" and select with $(".item_code", row). The addItem() function would benefit greatly from the same approach.

Solidity mapping returning null values

So basically, I create a mapping within a smart contract to store hashes of user data. It's mapped from a user id to the hash itself (a bytes32 value). I use a double sha256 hash and store it in the mapping with the aforementioned id. The function for storing it returns the hash by returning the values at the id in the mapping. This hash is correct, meaning at the very least it's initially stored correctly. However, I have another function that gets the hash from the id and it always returns a null value in the javascript tests. I am wondering if it's a problem with the test or with the contract itself.
pragma solidity ^0.4.22;
contract UserStore {
mapping(uint => bytes32) UserHashes; //User id to hash
event HashStored (
uint id,
bytes32 original,
bytes32 hash
);
function HashData(bytes32 data) returns (bytes32){
return sha256(abi.encodePacked(sha256(abi.encodePacked(data))));
}
function StoreHash(uint user_id, bytes32 data) external view returns (bytes32){
UserHashes[user_id] = HashData(data);
HashStored(user_id, data, UserHashes[user_id]);
return UserHashes[user_id];
}
/*
Gets the hash from the blockchain.
*/
function GetHash(uint u_id) view public returns (bytes32){
return UserHashes[u_id];
}
}
Everytime I run this test, GetHash returns a 0 value;
contract("Storage_Test", function(accounts) {
const args = {user_id: 0,
data: "This is some security data",
group_id : 15,
user_ids : [1,2,3,4,5],
num_accounts : 2
}
it("Hash Test: Multiple Storage and retrieving", async function() { return
await UserStore.deployed()
.then(async function(instance) {
var temp = args.data;
var _temp;
for (i = 1; i < args.num_accounts; i++) {
_temp = temp;
temp = await instance.HashData.call(temp);
// console.log("Datahash: " + temp);
result = await instance.StoreHash.call(i, _temp);
// console.log("Result: " + result);
assert.equal(result, temp, "Hash at " + i + " wasn't returned
correctly");
}
temp = args.data;
for (i= 1; i < args.num_accounts; i++) {
temp = await instance.HashData.call(temp);
result = await instance.GetHash.call(i);
assert.equal( result, temp, "Hash at " + i + " wasn't stored
correctly");
}
})
});
});
Change instance.StoreHash.call(...) to instance.StoreHash.sendTransaction(...). call() runs the function locally instead of submitting the transaction. The result is any state change isn’t persisted.

Parse Cloud Code getting Error Failed with: TypeError: Object 0 has no method 'set'

Im using Cloud Code for my Android App.
After saving a Value to a Parse Class I want to Update a field (credits) from my Users.
var query = new Parse.Query(Parse.User);
query.equalTo("householdOf", request.params.household);
query.find({
success: function(roomMates) {
for (var roomMate in roomMates)
{
if(roomMate != currentUser)
{
roomMate.set(
{
credit: 3
},
{
error: function(gameTurnAgain, error)
{
console.log("set failed " +error.code + error.message);
response.error("error");
}
});
}
}
this is my Cloud Code. I get the Error (TypeError: Object 0 has no method 'set') by roomMate.set
The roomMates must be Parse.User or am I wrong?
I am not professional in JS, but I am also playing with parse Cloude Code. So I suppose that you enumerate roomMates incorrectly.
You should enumerate array and get object like:
for (var i=0; i<roomMates.length; i++) {
roomMate = roomMates[i];
}
The key in enumerator works in key-value dictionaries to enumerate keys.
var dictionary = {key1 : "Hi", key2: "Bye"};
for (var key in dictionary) {
obj = dictionary[key];
}

Parse Cloud Code - How to query the User Class

I'm trying to query the Parse User Class but I'm not getting any results. The User class has a column labeled "phone", and I'm passing an array of dictionaries where each dictionary has a key "phone_numbers" that corresponds to an array of phone numbers. I'm trying to determine if a User in my table has one of those phone numbers. I'm not getting any errors running the code, but there does exist a user in my table with a matching phone number. What am I doing wrong?
Parse.Cloud.define("hasApp", function(request, response) {
var dict = request.params.contacts;
var num = 0;
var found = 0;
var error = 0;
var phoneNumbers = "";
for (var i = 0; i < dict.length; i++){
var result = dict[i].phone_numbers;
num += result.length;
for (var j = 0; j < result.length; j++){
phoneNumbers += result[j] + ", ";
var query = new Parse.Query(Parse.User);
query.equalTo("phone", result[j]);
query.find({
success: function(results) {
found = 1;
},
error: function() {
error = 1;
}
});
}
}
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
});
My response from calling this is
hasApp 337 numbers 352 found 0 error 0 phoneNumbers "list of phone numbers"
where some of those phone numbers appear in my User class. As far as I can tell I'm not getting any errors but I'm also not successfully querying the User table
UPDATE
After moving
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
to the body of the success block, I get the following error because I'm only allowed to call response.success once per cloud function.
Error Domain=Parse Code=141 "The operation couldn’t be completed. (Parse error 141.)"
UserInfo=0x14d035e0 {code=141, error=Error: Can't call success/error multiple times
at Object.success (<anonymous>:99:13)
at query.find.success (main.js:44:12)
at Parse.js:2:5786
at r (Parse.js:2:4981)
at Parse.js:2:4531
at Array.forEach (native)
at Object.w.each.w.forEach [as _arrayEach] (Parse.js:1:666)
at n.extend.resolve (Parse.js:2:4482)
at r (Parse.js:2:5117)
at Parse.js:2:4531}
Does this mean that I'm only able to verify one phone number at a time? So I can't pass an array of phone numbers and get the PFUser objects corresponding to those phone numbers (if they exist)?
I understand that my internal query to Parse.User is happening synchronously with my "hasApp" call, so is there a way to query Parse.User asynchronously? That way I can respond back to the client after checking all the phone numbers?
You can use Parse.Promise to solve logic where you need to iterate through O(n) number of database queries in one asynchronous Cloud Code definition:
var _ = require("underscore"),
isEmpty = function (o) { // standard function to check for empty objects
if (o == null) return true;
if (o.length > 0) return false;
if (o.length === 0) return true;
for (var p in o) {
if (hasOwnProperty.call(o, p)) return false;
}
return true;
};
Parse.Cloud.define("hasApp", function (request, response) {
var dict = request.params.contacts,
users = [];
var promise = Parse.Promise.as();
_.each(dict, function (obj) {
_.each(obj.phone_numbers, function (num) {
promise = promise.then(function () {
var promiseQuery = new Parse.Query(Parse.User);
promiseQuery.equalTo("phone", parseInt(num));
return promiseQuery.find({
success: function (result) {
if (isEmpty(result)) // don't save empty results e.g., "[]"
return;
users.push(result); // save results to a model to prevent losing it in scope
}
});
});
});
});
return promise.then(function () {
response.success("Found user(s): " + JSON.stringify(users));
});
});
Note a few things about this block:
You can append functionality iteratively to a Parse.Promise.
You can loose scope of database results in your iteration. Use a local array model to save your query results to. Although, I presume there is a better way to achieve the same functionality without the use of a user model, someone else can quote me on that.
Pay close attention to the way Parse handles data. For example, if you are storing your phone numbers as numbers, you have to make sure you use parseInt() when querying for it.
Be aware that you must attach your response.success() function to your promise to assure it is resolved after your iterations have run. From this block, your response from Parse will look similar to an array of User objects. You can decide on the many different ways you can save the data model depending on what you need it for.
As a final note, this block doesn't account for any validation or error handling that should be accounted for otherwise.
The problem seems to be that your response.success call is happening before the query can even happen. While you have response.success calls in your query success block, they are never called because you return success before the query is executed.
Try commenting out the line:
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
This should let the code go to your query, and maybe move it into the success block of your query.
Let me know if this works.
You're now calling response.success in a loop now. You should only call response.success/response.error once per cloud function.
It would help if you can show the original code with no commented out lines (to show your original intention) and the new code with no commented out lines as two separate code samples.
Querying a Parse.User is fairly easy and well explained in the documentation, here is an example taken from it
var query = new Parse.Query(Parse.User);
query.equalTo("gender", "female"); // find all the women
query.find({
success: function(women) {
// Do stuff
}
});
For your case it will be something like this:
Parse.Cloud.define("getAllFemales", function(request, response) {
var query = new Parse.Query(Parse.User);
query.equalTo("gender", "female"); // find all the women
query.find({
success: function(women) {
// Do stuff
}
});
});
Hope it helps, as always more info on the Documentation

Compiler error when combining Linq + "RangeVariables" + TPL + DynamicTableEntity

I'm looking at the Microsoft-provided sample "Process Tasks as they Finish" and adapting that TPL sample for Azure Storage.
The problem I have is marked below where the variable domainData reports the errors in the compiler: Unknown method Select(?) of TableQuerySegment<DynamicTableEntity> (fully qualified namespace removed)
I also get the following error DynamicTableEntity domainData \n\r Unknown type of variable domainData
/// if you have the necessary references the following most likely should compile and give you same error
CloudStorageAccount acct = CloudStorageAccount.DevelopmentStorageAccount;
CloudTableClient client = acct.CreateCloudTableClient();
CloudTable tableSymmetricKeys = client.GetTableReference("SymmetricKeys5");
TableContinuationToken token = new TableContinuationToken() { };
TableRequestOptions opt = new TableRequestOptions() { };
OperationContext ctx = new OperationContext() { ClientRequestID = "ID" };
CancellationToken cancelToken = new CancellationToken();
List<Task> taskList = new List<Task>();
var task2 = tableSymmetricKeys.CreateIfNotExistsAsync(cancelToken);
task2.Wait(cancelToken);
int depth = 3;
while (true)
{
Task<TableQuerySegment<DynamicTableEntity>> task3 = tableSymmetricKeys.ExecuteQuerySegmentedAsync(query, token, opt, ctx, cancelToken);
// Run the method
task3.Wait();
Console.WriteLine("Records retrieved in this attempt = " + task3.Result.Count());// + " | Total records retrieved = " + state.TotalEntitiesRetrieved);
// HELP! This is where I'm doing something the compiler doesn't like
//
IEnumerable<Task<int>> getTrustDataQuery =
from domainData in task3.Result select QueryPartnerForData(domainData, "yea, search for this.", client, cancelToken);
// Prepare for next iteration or quit
if (token == null)
{
break;
}
else
{
token = task3.Result.ContinuationToken;
// todo: persist token token.WriteXml()
}
}
//....
private static object QueryPartnerForData(DynamicTableEntity domainData, string p, CloudTableClient client, CancellationToken cancelToken)
{
throw new NotImplementedException();
}
Your code is missing a query. In order to test the code I created the following query:
TableQuery<DynamicTableEntity> query = new TableQuery<DynamicTableEntity>()
.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "temp"));
I also added the method QueryPartnerForData which doesn't do anything (simply returns null) and everything works fine. So maybe it's an issue with the QueryPartnerForData method? The best way to find the actual error is by setting a breakpoint here and there.
A StackOverflowException often means you are stuck in an endless loop. Run through the breakpoints a few times and see where your code is stuck. Could it be that QueryPartnerForData calls the other method and that the other method calls QueryPartnerForData again?

Resources