What I want to do is initialize a global variable outside of a function, set the variable within the function, and then print the variables value after the function. When I print however, it logs out No Message Provided.
In this case, I'm attempting to do this with the itemLocation variable.
var itemLocation;
Parse.Cloud.define("eBayCategorySearch", function (request, response) {
url = 'http://svcs.ebay.com/services/search/FindingService/v1';
Parse.Cloud.httpRequest({
url: url,
params: {
'OPERATION-NAME': 'findItemsByKeywords',
'SERVICE-VERSION': '1.12.0',
'SECURITY-APPNAME': '*APP ID GOES HERE*',
'GLOBAL-ID': 'EBAY-US',
'RESPONSE-DATA-FORMAT': 'JSON',
'itemFilter(0).name=ListingType': 'itemFilter(0).value=FixedPrice',
'keywords': request.params.item,
},
success: function (httpResponse) {
// parses results
var httpresponse = JSON.parse(httpResponse.text);
var items = [];
httpresponse.findItemsByKeywordsResponse.forEach(function (itemByKeywordsResponse) {
itemByKeywordsResponse.searchResult.forEach(function (result) {
result.item.forEach(function (item) {
items.push(item);
});
});
});
// count number of times each unique primaryCategory shows up (based on categoryId), returns top two IDs and their respective names
var categoryIdResults = {};
// Collect two most frequent categoryIds
items.forEach(function (item) {
var id = item.primaryCategory[0].categoryId;
if (categoryIdResults[id]) categoryIdResults[id]++;
else categoryIdResults[id] = 1;
});
var top2 = Object.keys(categoryIdResults).sort(function (a, b) {
return categoryIdResults[b] - categoryIdResults[a];
}).slice(0, 2);
console.log('Top category Ids: ' + top2.join(', '));
var categoryNameResults = {};
// Collect two most frequent categoryNames
items.forEach(function (item) {
var categoryName = item.primaryCategory[0].categoryName;
if (categoryNameResults[categoryName]) categoryNameResults[categoryName]++;
else categoryNameResults[categoryName] = 1;
});
var top2Names = Object.keys(categoryNameResults).sort(function (a, b) {
return categoryNameResults[b] - categoryNameResults[a];
}).slice(0, 2);
console.log('Top category Names: ' + top2Names.join(', '));
// compare categoryIdResults to userCategory object
//Extend the Parse.Object class to make the userCategory class
var userCategory = Parse.Object.extend("userCategory");
//Use Parse.Query to generate a new query, specifically querying the userCategory object.
query = new Parse.Query(userCategory);
//Set constraints on the query.
query.containedIn('categoryId', top2);
query.equalTo('parent', Parse.User.current())
//Submit the query and pass in callback functions.
var isMatching = false;
query.find({
success: function (results) {
var userCategoriesMatchingTop2 = results;
console.log("userCategory comparison success!");
console.log(results);
for (var i = 0; i < results.length; i++) {
itemCondition = results[i].get("itemCondition");
console.log(itemCondition);
itemLocation = results[i].get("itemLocation");
console.log(itemLocation);
minPrice = results[i].get("minPrice");
console.log(minPrice);
maxPrice = results[i].get("maxPrice");
console.log(maxPrice);
itemSearch = request.params.item;
console.log(itemSearch);
}
if (userCategoriesMatchingTop2 && userCategoriesMatchingTop2.length > 0) {
isMatching = true;
}
response.success({
"results": [{
"Number of top categories": top2.length
}, {
"Top category Ids": top2
}, {
"Top category names": top2Names
}, {
"Number of matches": userCategoriesMatchingTop2.length
}, {
"User categories that match search": userCategoriesMatchingTop2
}, {
"Matching Category Condition": itemCondition
}, {
"Matching Category Location": itemLocation
}, {
"Matching Category MaxPrice": maxPrice
}, {
"Matching Category MinPrice": minPrice
}, {
"Search Term": itemSearch
},
]
});
console.log('User categories that match search: ', results);
},
error: function (error) {
//Error Callback
console.log("An error has occurred");
console.log(error);
}
});
},
error: function (httpResponse) {
console.log('error!!!');
response.error('Request failed with response code ' + httpResponse.status);
}
});
});
console.log(itemLocation);
I'm unsure what you are trying to achieve, but this is one way to do what you suppose to do.
var itemLocation;
var promise; // variable holding the promise
Parse.Cloud.define("eBayCategorySearch", function (request, response) {
url = 'http://svcs.ebay.com/services/search/FindingService/v1';
// set the promise
promise = Parse.Cloud.httpRequest({
// your code goes here (setting the variables)
});
});
// once the promise has been resolved
promise.then(function(resp){
console.log(itemLocation);
});
Related
New to writing async/await functions in javascript. I just can't seem to get these async/await keywords in the right place. The following code provides a function maCreateWin911CcsTemplate(executionContext, id) which creates an email record with a template in D365 CRM in which in turn calls another function getNewestLicenseTrackingRecord(executionContext, maId) that returns 2 values in an array I need to insert into the email record template passed through an action.
async function maCreateWin911CcsTemplate(executionContext, id)
{
debugger;
var formContext = executionContext;
var maId = id;
maId = maId.toString().replace("{", "").replace("}", "");
var newestLtRecordSnAndLocation = new Array(2);
newestLtRecordSnAndLocation = getNewestLicenseTrackingRecord(executionContext, maId);
var sn = await newestLtRecordSnAndLocation[0];
var sysLocation = newestLtRecordSnAndLocation[1];
var parameters = {};
parameters.sn = sn;
parameters.sysLocation = sysLocation;
var target = {entityType: "new_maintenancecontract", id: maId};
parameters.entity = target;
parameters.getMetadata = function ()
{
return {
boundParameter: "entity",
operationType: 0,
operationName: "new_MAActionCreateWIN911CCSEmail",
parameterTypes:
{
"sn":
{
"typeName": "Edm.String",
"structuralProperty": 1
},
"sysLocation":
{
"typeName": "Edm.String",
"structuralProperty": 1
},
"entity":
{
"typeName": "new_maintenancecontract",
"structuralProperty": 5
}
},
};
}
Xrm.WebApi.online.execute(parameters).then(
function success(result) {
if(result.ok){
result.json().then(function (results) {
var emailId = results.emailId;
emailId = emailId.substring(61, 97);
Xrm.Utility.openEntityForm("email",emailId);
})
}
else
{
Xrm.Utility.alertDialog("Unknown error occured in ISV code.");
}
},
function (error) {
Xrm.Utility.alertDialog(error.message);
}
);
}
function getNewestLicenseTrackingRecord(executionContext, maId)
{
debugger;
var executionContext = executionContext;
var maId = maId;
maId = maId.toString().replace("{", "").replace("}", "");
parent.Xrm.WebApi.retrieveMultipleRecords("new_license", "?$select=createdon,new_licenseno,new_systemlocation&$filter=_new_maid_value%20eq%20" + '<guid>' + "%20&$top=1&$orderby=createdon%20desc").then(
function success(result) {
for (var i = 0; i < result.entities.length; i++) {
alert(result.entities[i].createdon + " : " + result.entities[i].new_licenseno + " : " + result.entities[i].new_systemlocation);
if(result.entities[i].new_licenseno === null)
{
var licenseNo = "";
}
else
{
var licenseNo = result.entities[i].new_licenseno.toString();
}
if(result.entities[i].new_systemlocation === null)
{
var systemLocation = "";
}
else
{
var systemLocation = result.entities[i].new_systemlocation.toString();
}
var ltArray = new Array(2);
ltArray = [licenseNo, systemLocation];
return ltArray;
//break; // just for code demo
}
},
function(error) {
alert("Error: " + error.message);
}
);
}
As you can see from above, I am returning an array with 2 values in the getNewestLicenseTrackingRecord(executionContext, maId) however, one of the values is always returning undefined because of an uncaught promise as seen below:
I've been fighting with moving the async/await keywords around and have not been successful in getting both values. Any help would be much appreciated.
I am trying to push array content in a global defined empty array & then retrieve its contents inside another function.
Below is the code which i tried:
describe('My Test', function() {
var arrayf3=[];
var indexf3='not found';
it('Test starts', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.w3schools.com/angular/');
var elm = element(by.id('leftmenuinner')).all(By.css('[target="_top"]'));
elm.count().then(function(count) {
Methods.pushToArray(0, count, elm);
})
var texttocheck='Data Binding';
Methods.getIndex(0, arrayf3.length, arrayf3, texttocheck);
console.log('Text content of global array is ' + arrayf3);
console.log('index of the array number having texttofind is ' + indexf3);
})
var Methods = {
getIndex :function (i, max, array, texttocheck) {
if (i < max) {
console.log('text[' + i + '].indexOf = ' + array[i].indexOf(texttocheck))
if (array[i].indexOf(texttocheck) > 0) {
indexf3 = i;
} else {
Methods.getIndex(i + 1, max, array, texttocheck);
}
}
},
pushToArray :function (i, max, elm) {
if (i < max) {
elm.get(i).getText().then(function(tmpText) {
console.log("The array "+tmpText);
arrayf3.push(tmpText);
})
Methods.pushToArray(i + 1, max, elm);
}
},
}
});
Problem is i am getting null values for below placeholder values:
Text content of global array is
index of the array number having texttofind is
I want the array value copied in this global empty array to be used & displayed in the same it block function 'Test starts'
Protractor's element.all inherently knows how to getText() on each of the elements and return the values as an array.
it('Test starts', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.w3schools.com/angular/');
var getIndexOfElementByPartialText = function(inputText) {
return element(by.id('leftmenuinner')).all(by.css('[target="_top"]')).getText().then(function(values) {
var indexNumber;
values.forEach(function(value, index) {
if (new RegExp(inputText).test(value)) {
if (indexNumber === undefined) {
indexNumber = index;
} else {
throw new Error('multiple elements match the input text');
}
}
});
if (indexNumber === undefined) {
throw new Error('no elements match the input text');
} else {
return indexNumber;
}
});
});
expect(getIndexOfElementByPartialText('thing1').toBe(1);
expect(getIndexOfElementByPartialText('thing2').toBe(2);
});
Edited the answer to provide it in terms of a re-usable function.
Why is my code not progressing? I tested it in both Angular and Express and the code progressed limited only by the inability to edit the User table with new data because the Master Key is necessary. Where am I going wrong?
Parse.Cloud.define("someFunction", function(request, response) {
Parse.Cloud.useMasterKey();
var user = Parse.Object.extend("User");
var query = new Parse.Query(Parse.User);
var Table1 = Parse.Object.extend("Table1");
var table1Query = new Parse.Query(Table1);
var Table2 = Parse.Object.extend("Table2");
var table2Query = new Parse.Query(Table2);
var Ids = request.params.data; //this is an array of Parse.Object Ids
var array = [];
var x = Ids.length;
while (x--){
var Id = Ids[x];
console.log("This is active");//I know this working
table1Query.equalTo("user", {__type: "Pointer", className: "_User",
objectId: Id});
table1Query.find({
success: function (results) {
var resultIds = _.map(results, function (n) {
return n.id});
var resultObjs = _.map(results, function (n) {
return return _.extend(_.find(n), {id: n.id})});
var a = resultIds.length;
while (a--) {
var resultId = resultIds[a];
console.log("I don't know why this is not coming up!?!");//Why isn't this working?
table2Query.equalTo("user", {__type: "Pointer", className: "_User",
objectId: resultId});
table2Query.find({
success: function (items) {
var MA = _.map(_.flatten(items), function (n) {
return _.find(n)});
var step3 = _.map(resultObjs, function (n) {return _.extend(n, {
Matched: _.filter(MA, function (a) {return a.result.id == n.id})})});
var total = Math.round(_.reduce(_.map(step3, function (n) {return n.Bill
}), function (memo, num) {return memo + num;}, 0) * 100) / 100;
var duty = function (total, id) {
var promise = new Parse.Promise();
table2Query.get(id, {
success: function (Answer) {
Answer.set("duty", total);
Answer.save().then(function (difresult) {
response.success(difresult);
}, function (error) {
response.error(error);})
}
});
}
array.push(duty(Answer, Id));
}
})
}
}
})
}
return
Parse.Promise.when(array).then(function() {
response.success("Successfully retrieved Total Bills.");
},
function(error) {
response.error("Something is still wrong");
console.log(error);
});;
})
Let's fix some coding errors first before I can continue.
Add ';' at the end of the below code.
var Ids = req.params.data
var x = Ids.length
var a = resultIds.length
array.push(duty(Answer, Id))
Then change req to request
var Ids = req.params.data
to
var Ids = request.params.data
I am trying to read a file on parse.com and using a for loop iterate over all the records present in it. On each record, I need to perform 4 operations, each dependent on the other. Can someone please guide how I can do that so that each record is processed in the for loop.
Parse.Cloud.httpRequest({
url: urlValue
}).then(function(fileResponse) {
console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
// console.log("processUploadFile:Text:" + fileResponse.text);
var records = fileResponse.text.split("\r");
for (var i = 0; i < records.length; ++i) {
// console.log("Record:" + i + " detail:" + records[i] + "\n\n");
var record = records[i];
console.log("processUploadFile:adding patient");
Parse.Cloud.run("addPatient", {
record:record
}, {
success: function(objectId) {
console.log("Created objectId:" + JSON.stringify(objectId));
Parse.Cloud.run("addProvider", {
record:record
}, {
success: function(objectId) {
console.log("Created objectId:" + JSON.stringify(objectId));
Parse.Cloud.run("addLocation", {
record:record
}, {
success: function(objectId) {
console.log("objectId:" + JSON.stringify(objectId));
},
error: function(error) {
console.log(JSON.stringify(error));
}
});
},
error: function(error) {
console.log(JSON.stringify(error));
}
});
},
error: function(error) {
console.log(JSON.stringify(error));
}
});
};
}
}
response.success();
});
The right right answer depends on the semantics of those operations, whether they depend on each other in any way. The other part of a right right answer accounts for transaction rate limits and timeouts imposed by parse.com. That also depends on what happens in the cloud operations and how much data is being processed.
But the right answer (as opposed to right right) is to perform operations serially by chaining promises' then(), and to perform groups of operations concurrently (or in arbitrary order) with Parse.Promise.when().
One such ordering would look like this:
var patientQs = [];
var providerQs = [];
var locationQs = [];
var records;
Parse.Cloud.httpRequest({url: urlValue}).then(function(fileResponse) {
console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
records = fileResponse.text.split("\r");
for (var i = 0; i < records.length; ++i) {
// console.log("Record:" + i + " detail:" + records[i] + "\n\n");
var record = records[i];
patientQs.push(Parse.Cloud.run("addPatient", {record:record}));
providerQs.push(Parse.Cloud.run("addProvider", {record:record}));
locationQs.push(Parse.Cloud.run("addLocation", {record:record}));
}
return Parse.Promise.when(patientQs);
}).then(function() {
// since the result of addPatient is an objectId, arguments
// will be the corresponding objectIds for each run
for (var i=0; i<arguments.length; i++) {
console.log(arguments[i] + " is the object id for input record " + JSON.stringify(records[i]));
}
return Parse.Promise.when(providerQs);
}).then(function() {
return Parse.Promise.when(locationQs);
}).then(function() {
response.success();
}, function(error) {
response.error(error);
});
This says, "go thru the http-retrieved records, and first add all of the patients for those records, then add all of the providers, and so on".
Or, you could group the operations by input record, like this:
Parse.Cloud.httpRequest({url: urlValue}).then(function(fileResponse) {
console.log("processUploadFile:httpRequest:response:" + JSON.stringify(fileResponse.buffer.length));
var records = fileResponse.text.split("\r");
var recordQs = [];
for (var i = 0; i < records.length; ++i) {
// console.log("Record:" + i + " detail:" + records[i] + "\n\n");
var record = records[i];
recordQs.push(processARecord(record));
}
return Parse.Promise.when(recordQs);
}).then(function() {
response.success(arguments);
}, function(error) {
response.error(error);
});
function processARecord(record) {
var result = {};
return Parse.Cloud.run("addPatient", {record:record}).then(function(objectId) {
console.log(objectId + " is the object id for input record " + JSON.stringify(record));
result.patientId = objectId;
return Parse.Cloud.run("addProvider", {record:record});
}).then(function (providerId) {
result.providerId = providerId;
return Parse.Cloud.run("addLocation", {record:record});
}).then(function(locationId) {
result.locationId = locationId;
return result;
});
}
I'm trying to make an XML based menu with JavaScript, XML and jQuery. I've been successful at getting the categories of the menu, but haven't been able to generate the items in the categories.
My script is as follows, and later in this thread, I've asked for suggestions for this code:
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function() {
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: function parse(xmlResponse) {
var data = $("item", xmlResponse).map(function() {
return {
id: $("animal_id", this).text(),
title: $("animal_title", this).text(),
url: $("animal_url", this).text(),
category: $("animal_category", this).text().split('/'),
};
}).get();
var first_item = category_gen(data, 0);
$('ul.w-nav-list.level_2').append(first_item);
var categnumber = new Array();
for (i = 1; i <= data.length; i++) //for splitting id, and getting 0 for category_number (1 or 2 or 3...and so on)
{
categnumber[i] = data[i].id.split('_');
console.log(categnumber[i][0]);
for (j = 1; j <= data.length; j++) //appending via a function.
{
var data_text = category_or_animal(data, categnumber, j);
console.log(data_text);
$('ul.w-nav-list.level_2').append(data_text);
}
}
function category_or_animal(d, catg, k) {
var catg1 = new Array();
var catg2 = new Array();
var catg1 = d[k].id.split('_');
if (d[k - 1]) {
var catg2 = d[k - 1].id.split('_');
//if(d[k-1].id)
if (catg1[0] != catg2[0])
return category_gen(d, k);
} else
return '</ul>' + animal_gen(d, k);
}
function category_gen(d, z) {
var category_var = '<li class="w-nav-item level_2 has_sublevel"><a class="w-nav-anchor level_2" href="javascript:void(0);"><span class="w-nav-title">' + d[z].category + '</span><span class="w-nav-arrow"></span></a><ul class="w-nav-list level_3">';
return category_var;
}
function animal_gen(d, z) {
var animal_var = '<li class="w-nav-item level_3"><a class="w-nav-anchor level_3" href="animals/' + d[z].url + '"><span class="w-nav-title">' + d[z].title + '</span><span class="w-nav-arrow"></span></a></li>';
return animal_var;
}
}, error: function() {
console.log('Error: Animals info xml could not be loaded.');
}
});
});
Here's the JSFiddle link for the above code: http://jsfiddle.net/mohitk117/d7XmQ/4/
In the above code I need some alterations, with which I think the code might work, so I'm asking for suggestions:
Here's the function that's calling separate functions with arguments to generate the menu in above code:
function category_or_animal(d, catg, k) {
var catg1 = new Array();
var catg2 = new Array();
var catg1 = d[k].id.split('_');
if (d[k - 1]) {
var catg2 = d[k - 1].id.split('_');
//if(d[k-1].id)
if (catg1[0] != catg2[0])
return category_gen(d, k);
} else
return animal_gen(d, k) + '</ul>';
}
At the if(catg1[0] != catg2[0]) it checks if the split string 1_2 or 1_3 is equal to 1_1 or 1_2 respectively. By split, I mean the first element: 1 .... if you have a look at the xml: [ :: Animals XML :: ], you'll see that the animal_id is in the format of %category_number% _ %item_number% ... So I need to create the menu with CATEGORY > ITEM (item=animal name)
Now if I could return category_gen() + animal() with animal(){ in a for loop for all the matching category id numbers} then maybe this could be complete! But I don't of a count script for conditioning the for loop (i=0;i<=count();i++)...
Would anyone know of how to get this script functioning?
Hard to tell what the provided JSFiddle is trying to do.
This is my best stab at it. I used JQuery to parse the XML out into categories and generate lists of items.
http://jsfiddle.net/d7XmQ/8/
"use strict";
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function () {
var $menu = $('#menu');
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: handleResponse,
error: function () {
console.log('Error: Animals info xml could not be loaded.');
}
});
function handleResponse(xmlResponse) {
var $data = parseResponse(xmlResponse);
createMenu($data);
}
function parseResponse(xmlResponse) {
return $("item", xmlResponse).map(function () {
var $this = $(this);
return {
id: $this.find("animal_id").text(),
title: $this.find("animal_title").text(),
url: $this.find("animal_url").text(),
category: $this.find("animal_category").text()
};
});
}
function createMenu($data) {
var categories = {};
$data.each(function (i, dataItem) {
if (typeof categories[dataItem.category] === 'undefined') {
categories[dataItem.category] = [];
}
categories[dataItem.category].push(dataItem);
});
$.each(categories, function (category, categoryItems) {
var categoryItems = categories[category];
$menu.append($('<h2>').text(category));
$menu.append(createList(categoryItems));
});
}
function createList(categoryItems) {
var $list = $('<ul>');
$.each(categoryItems, function (i, dataItem) {
$list.append(createItem(dataItem));
});
return $list;
}
function createItem(dataItem) {
return $('<li>').text(dataItem.title);
}
});
You can solve this without using any for/while loop or forEach.
function myCounter(inputWords) {
return inputWords.reduce( (countWords, word) => {
countWords[word] = ++countWords[word] || 1;
return countWords;
}, {});
}
Hope it helps you!