executeQueryAsync callback function execute occasionally - sharepoint

I have to create publishing page with custom layout using JSOM and the code is working fine. But in my executeQueryAsync success callback, i am trying to get id of the item created. So, sometimes i get the alert with id and sometimes page refreshes without executing success callback. can someone guide me?
wikiPage.set_item("Title",pageName1)
wikiPage.update();
ctx.executeQueryAsync(Function.createDelegate(this, function(){
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(
"<View Scope='RecursiveAll'><Query>" +
"<Where>" +
"<Eq><FieldRef Name=\"FileLeafRef\"/><Value Type=\"Text\">" + pageName + "</Value></Eq>" +
"</Where>" +
"</Query></View>");
collListItem = wikiPages.getItems(camlQuery);
ctx.load(collListItem);
ctx.executeQueryAsync(Function.createDelegate(this, function(){
var listItemEnumerator = collListItem.getEnumerator();
while(listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
alert(oListItem.get_id());}
}),Function.createDelegate(this, this.onQueryFailed));
}),
Function.createDelegate(this, this.onQueryFailed));

Try to load the page when you updating instead of querying again.
Demo:
wikiPage.update();
ctx.load(wikiPage);
ctx.executeQueryAsync(
function () {
debugger;
alert(wikiPage.get_item("ID"));
},
error);

Related

Is there any way with suitescript 1.0 to run a server side function on a client script (like getFieldText)?

I was writing a client script for work and part of it involved getting getting the value of the cost category's text to display to the user. Unfortunately, that seems to only be a server side function. I've seen some posts about how to accomplish this in Suitescript 2.0, but for whatever reason, I can't seem to get Suitescript 2.0 scripts to work on Netsuite. Is there any way to run the getFieldText function from the client side script in 1.0?
I was able to use a separate Suitelet script to get the job done.
Code from the suitelet:
function getFTxt(request, response){
try{
var recordid = request.getParameter('rid');
var recordtype = request.getParameter('rt');
record = nlapiLoadRecord(recordtype, recordid);
var fieldName = request.getParameter('fn');
fieldText = record.getFieldText(fieldName);
response.write(fieldText);
}
catch(e){
var err = '';
if ( e instanceof nlobjError ){
err = 'System error: ' + e.getCode() + '\n' + e.getDetails();
}
else{
err = 'Unexpected error: ' + e.toString();
}
var errmsg = 'Error: ';
errmsg+= '\n' + err;
nlapiLogExecution( 'ERROR', 'Error is: ', errmsg);
response.write("");
}
}
Code from my original script:
function getFieldText(field,item){
var url = nlapiResolveURL('SUITELET', 'customscriptScriptIdGoesHere', 'customdeployDeployIdGoesHere') + '&rid=' + item.getId() + '&rt=' + item.getRecordType() + '&fn=' + field;
var response = nlapiRequestURL(url);
return response.getBody();
}
Then, whenever I wanted to get the field text for an item, I'd call that function from within the script.
be sure to replace the script and deployment id to that of the suitelet.

Click function not executing executing Nightmare.js

I'm trying to do some scraping with nightmare and my work is almost functional. The problem is that I'm facing an issue when I try to perform a click() after the evaluate() and run() have been called. After I run those two functions I'm trying to perform another click to move myself to another part of the website, but is not executing the click().
At this point I'm note sure whats the issue, I have few assumptions, maybe those functions are asynchronous and I'm trying to click() when the callbacks arent ready yet or one of those functions ends de current nightmare object and I dont have the scope anymore.
var Nightmare = require('nightmare');
//var nightmare = Nightmare({show:true})
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
var urlWeb = "someurl";
var selectCity = "#ddl_city";
var selectTheater = "#ddl_theater";
var enterBtn = "#btn_enter";
var mainSelector = "#aspnetForm";
var flagReady = true;
new Nightmare({show:true})
.goto(urlWeb)
.wait(selectCity)
.select(selectCity, '19')
.wait(8000)
.select(selectTheater, '12')
.wait(1000)
.click(enterBtn)
.wait(mainSelector)
.evaluate(function(){
//returning HTML for cheerio
return document.body.innerHTML;
})
.run(function(err, nightmare){
if (err) return console.log(err);
// Loading HTML body on jquery cheerio
var $ = cheerio.load(nightmare);
//Looping on each div for seccion de Carterla para Hoy
$('.showtimeDaily').each(function(index, element){
//spanish title
console.log($(this).find('h3').children().text());
//english title
console.log($(this).find('h4').text());
//schedule for today
console.log($(this).find('li').children().text() + " ");
//img for movie
console.log($(this).find('img').attr('src'));
//show time data such as gender, lenght, language
console.log($(this).find('.showtimeData').text());
var showtimeData = $(this).find('.showtimeData').text();
//console.log(JSON.stringify(showtimeData.replace(/\t|\n/g, "")));
})
console.log('Done!');
})
//*****here is wen I try to click*****
.click('a[href="../showtimes/weekly.aspx"]');
I was having issue with the asynchronous call backs, so what I did is that I nested calls of the nightmare object to make sure that the tasks were running one after the other one. This is the code:
nightmare
.goto(urlWeb)
.wait(selectCity)
.select(selectCity, '19')
.wait(8000)
.select(selectTheater, '12')
.wait(1000)
.click(enterBtn)
.wait(mainSelector)
.evaluate(function(){
//returning HTML for cheerio
return document.body.innerHTML;
})
.then(function(body){
// Loading HTML body on jquery cheerio
var $ = cheerio.load(body);
//Looping on each div for seccion de Carterla para Hoy
$('.showtimeDaily').each(function(index, element){
//spanish title
console.log($(this).find('h3').children().text());
//english title
console.log($(this).find('h4').text());
//schedule for today
console.log($(this).find('li').children().text() + " ");
//img for movie
console.log($(this).find('img').attr('src'));
//show time data such as gender, lenght, language
console.log($(this).find('.showtimeData').text());
var showtimeData = $(this).find('.showtimeData').text();
//console.log(JSON.stringify(showtimeData.replace(/\t|\n/g, "")));
})
//**Here I call nightmare to run after the first call back is done*****
nightmare
.goto('')
.wait('body')
.title()
.then(function(title){
console.log(title);
});
console.log('Done!');
});

Maximo Anywhere - Dynamic List Creation using Work Execution App

I am customizing Anywhere(7.5.2)-WorkExecution. I am trying to create a dynamic list on the Work Log execution but it always creates only one. Kindly help.
CREATE Action
Work Log
File: WorkLogHandler.js
Function: _saveTransaction
Existing Code:
_saveTransaction: function(){
try{
var workOrderSet = CommonHandler._getAdditionalResource(this,"workOrder");
var workOrder = workOrderSet.getCurrentRecord();
if (!workOrder.isNew()) {
ModelService.save(workOrderSet);
}
this.ui.hideCurrentView();
}catch(e){
throw e;
}
},
New Code:
_saveTransaction: function(){
debugger;
try{
var workOrderSet = CommonHandler._getAdditionalResource(this,"workOrder");
var workLogdata = CommonHandler._getAdditionalResource(this,'workOrder.workloglist').getCurrentRecord();
var workOrder = workOrderSet.getCurrentRecord();
debugger;
for(var i=0; i<2; i++){
debugger;
if (!workOrder.isNew()) {
debugger;
workLogdata.set('summary',i+" Round");
}
ModelService.save(workLogdata);
this.ui.hideCurrentView();
}
return;
}catch(e){
throw e;
}
},
If you're trying to create a new worklog entry every time the record is saved, the issue is here..
var workLogdata = CommonHandler._getAdditionalResource(this,'workOrder.workloglist').getCurrentRecord();
You need to create a new record for each new worklog that you're trying to add, not retrieve the current one.
var workLogdata = CommonHandler._getAdditionalResource(this,'workOrder.workloglist').createNewRecord()

Return a value from phantomjs to nodejs

I'm using phantomjs using jquerygo library and am trying to this.
Visit a url
Click on a link and wait for it to load
Grab a particular tag and return it to nodejs for processing.
I realize that in phantomjs:
The execution is sandboxed, the web page has no access to the phantom object and it can't probe its own setting
But I should be able to return a simple string from the evaluate right?
But that is not working. My code is as follows:
var photogsScrapeCount = function(url, callback){
console.log("LOADED PHOTOGSSCRAPE Count");
url = decodeURIComponent(url);
//$.config.site = 'https://www.magnumphotos.com/';
$.config.addJQuery = false;
$.visit(url, function() {
$.waitForElement(".7n7np102",function() {
$.getPage(function(page) {
var imgCounterMinus = page.evaluate(function(){
$(".7n7np102 a").click(); // open the image enlarge
var temp = setTimeout(function(){
imgCounterMinus1 = $("span[id$='TotalPageCount_Lbl']").html();
imgCounterMinus1 = imgCounterMinus1.split(" ");
imgCounterMinus1 = imgCounterMinus1[2];
imgCounterMinus1 = parseInt(imgCounterMinus1);
console.log("imgCounterMinus1" + imgCounterMinus1);
return (imgCounterMinus1 - 3);
}, 4000);
return temp;
});
//console.log("After evaluate: " + imgCounterMinus)
});
});
});
};
Can this be achieved in any different way? The basic example from website is working so I am assuming that the setTimeout is giving me problems.
Any ideas or suggestions would be very helpful as I have very little experience in writing jquery, Js.
The docs say (emphasis mine):
For one, this library is not a complete API mirror of jQuery. Every API is asynchronous (due to its interaction with Phantom.js), so there are some differences.
There is also an example how page.evaluate() must be used. The result is not returned, but passed into a second callback. There is no way to return something from an asynchronous execution of a function except by using the callback. So the setTimeout syntax is also wrong.
$(".7n7np102 a").click(function(){
setTimeout(function(){
$.getPage(function(page) {
page.evaluate(function(){
var imgCounterMinus1 = $("span[id$='TotalPageCount_Lbl']").html();
imgCounterMinus1 = imgCounterMinus1.split(" ");
imgCounterMinus1 = imgCounterMinus1[2];
imgCounterMinus1 = parseInt(imgCounterMinus1);
console.log("imgCounterMinus1" + imgCounterMinus1);
return (imgCounterMinus1 - 3);
}, function(err, result){
console.log("After evaluate: " + result);
callback();
$.close();
});
});
}, 4000);
});

Store a variable in Intern funcational test

How can you store a value from one element in an Intern functional test that can be used to find additional elements?
For example, I have the following test snippet:
var mainItem = "Menu 1";
var subItem = "Sub Menu 1";
var mainItemId = "";
return this.remote
.elementByXPath("//*[contains(text(),'" + mainItem + "')]/ancestor::*[#dojoattachpoint='focusNode']")
.getAttribute("id")
.then(function(id){ mainItemId = id; })
.clickElement()
.end()
.wait(500)
.then(function(){ console.log(mainItemId); })
.elementByXPath("//*[contains(text(),'" + subItem + "')][ancestor::*[#dijitpopupparent='" + mainItemId + "']]")
.clickElement()
.end()
Basically, when I run the test, the mainItemId value will log correctly, but the second elementByXPath will not be found. If I initialize mainItemId with the same value, the xpath works. Based on what I'm seeing, its as if mainItemId will store the value only within the .then() context.
Thanks.
All of the remote methods are non-blocking, and execute immediately when the test function is invoked. mainItemId is not set until after the 4th command is executed. If you need to perform a query that is conditional upon data retrieved from an earlier command, you need to do that within a callback:
var mainItem = "Menu 1";
var subItem = "Sub Menu 1";
var mainItemId = "";
var remote = this.remote;
return remote
.elementByXPath("//*[contains(text(),'" + mainItem + "')]/ancestor::*[#dojoattachpoint='focusNode']")
.getAttribute("id")
.then(function(id){ mainItemId = id; })
.clickElement()
.end()
.wait(500)
.then(function(){
return remote.elementByXPath("//*[contains(text(),'" + subItem + "')][ancestor::*[#dijitpopupparent='" + mainItemId + "']]")
.clickElement()
.end()
});

Resources