I feel I have a fairly simple problem but every solution online is seriously complicated. I am in SharePoint designer 2010 and I am not a programmer but I can get by. I have a SP list with Contract Numbers and when you click the contract number it brings you to the item. I just want JavaScript code that will read the value from the list (by ID or however) and store it in a variable.
For example:
var siteUrl = 'https://...';
var itemID = 22;
var TargetListItem;
Function onLoad(){
var context = new SP.ClientContent(siteUrl);
var web = context.get_web().get_lists().getByTitle('Data Call');
var list = web.getItemById(itemID);
context.load(list, 'Contract Number');
var value = list.get_item('Contract Number');
var url = "/sites/... " + value + "...";
return url
}
The code works if I hard-code value so that the URL returned has a parameter, but not when I set value above. Please if anyone has a really simple way to accomplish this let me know!
You are missing SP.ClientContext.executeQueryAsync method that executes the current pending request asynchronously on the server
SP.ClientContext.executeQueryAsync method has the following signature:
SP.ClientContext.executeQueryAsync(succeededCallback, failedCallback)
and since it is async method you cant return from your method, but have to declare succeededCallback function that contains the returned results.
When working with asynchronous API such as JSOM the following patterns are commonly used:
Using nested callbacks
Using the promises pattern
Please refer Asynchronous programming in apps for Office article to get acquainted with asynchronous programming for SharePoint.
The below example demonstrates how to get list item using callback approach:
function getItem(listTitle,itemId,success,error){
var context = SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(listTitle);
var listItem = list.getItemById(itemId);
context.load(listItem);
context.executeQueryAsync(
function() {
success(listItem);
},
error
);
}
Example
getItem('Data Call', 22,
function(item){
var result = item.get_item('Contract Number');
},
function(sender,args){
console.log(args.get_message());
}
);
References
How to: Create, Update, and Delete List Items Using JavaScript
Asynchronous programming in apps for Office
Related
I have a list of URL, say 4 of them. For each I'd like to scrape some information and store the information into a global variable called allData. So my code looks like this:
var request = require('request');
var cheerio = require('cheerio');
var urls = [url1,url2,url3,url4];
var allData = [];
for(var url in urls){
request(url, function(err,response,body){
var $ = cheerio.load(body);
var data = $('h1.large','#title_main').text();
allData.push(data);
});
}
However, I realize this won't work due to the asynchronous nature of using request. In the last loop, all data in "datas" are all the same and come from url4. Any idea how I can fix this? Really need this functionality.
Glad you found a solution that worked for you.
You might know about this as 9 months have passed by, but for future reference you could also use some native javascript Array functions that "close" on the scope for each iteration (and avoid having another dependency for your project) -- I do this all the time in some of my internet scrapers using .forEach():
urls.forEach(function(url){
request(url, function(err,response,body){
var $ = cheerio.load(body);
var data = $('h1.large','#title_main').text();
allData.push(data);
});
})
There are a handful of functional programing based methods that exist in the Array.prototype that allow you to execute a function on every iteration (essentially freezing the parameters that go into the function) of the data in the array. There are a handful of functions like .forEach() that allow you to close on parameters within a loop that has asynchronous code in it.
The code above results in four methods being executed, asynchronously. Each method is passed one of the url's in your array. allData will have results appended from contents of the requests/cheerio parsing as each request finishes.
If you need them to be in order, you can access the index passed along with each forEach function iteration:
urls.forEach(function(url,index){
request(url, function(err,response,body){
var $ = cheerio.load(body);
var data = $('h1.large','#title_main').text();
allData[index]=data;
});
})
Hi I am new to Angular and javascript and need a bit of help.
I have a service that will need to aggregate data from various locations. I am building a sub-service to pull data from one of these locations. This subservice needs to 1) retrieve data from a REST web service, 2) massage it a bit and 3) return the final data to the invoking service.
I have steps 1 and 2 working, however I am running into a problem on the third. In general, I am having a hard time understanding promises. Yes, I've read the documentation, googled around, even saw a cartoon on it, still can't figure it out.... Anyway, here is the relevant code:
app.service('advsolr',['$http',function($http) {
var DEBUG = false;
var conf = get_conf();
var solr = 'serverurl';
var res = {};
var data = {};
this.query = function(searchp) {
//Run Search
query_solr(searchp);
return data;
};
var query_solr = function(search) {
var g = 'serverurl' //works fine
if (DEBUG) { console.log(g);}
$http.get(g).then(function(response){
res = response.data; // this works
parse_search_res(); //this massages the data and sticks it in the data object
return data; //this does absolutely nothing here
});
};
}]);
The main query method is ran by the other service. This queries a Solr instance, gets the results and massages them into the format I want. I know I can do this elsewhere, but I want to have this as a standalone service for portability and plus I just want this to work dammit.
So the query method runs, I had some other stuff in there, but I took it out for this example since it would not add value. It hits query_solr which gets the data and massages it with parse_search_res, which sticks it into the data global variable.
Now the issue is that query method returns the empty data before parse_search_res had a chance to load the data in it. How can I prevent the query method from returning without the data?
Thanks
The idea of promises is that you initiate some asynchronous operation like AJAX request, then you return corresponding promise object, and a consumer code uses this promise's methods to provide callback function on promise state change.
So to fix your code you need to make query_solr return promise:
app.service('advsolr', ['$http',function($http) {
var DEBUG = false;
var conf = get_conf();
var solr = 'serverurl';
var res = {};
var data = {};
var query_solr = function(search) {
var g = 'serverurl' //works fine
if (DEBUG) { console.log(g);}
return $http.get(g).then(function(response){
res = response.data; // this works
return parse_search_res();
});
};
this.query = function(searchp) {
return query_solr(searchp);
};
}]);
You'll also need to change parse_search_res() to return the massaged data instead of saving it into the "data" variable.
And having set up advsolr service like that, one could use it like this:
advsolr.query('something').then(function(data) {
console.log(data);
});
I have simple table scripts in Azure written in javascript and node.js.
Now, if I call any of these from Windows Phone, the object parameter gets updated automatically from the return value. And thus code like this works
await table1.InsertAsync(val1);
MyObj val2 = new MyObj();
val2.data = val1.Id;
await table2.InsertAsync(val2);
However now I try to utilize this same from scheduled job in Azure: essentially chaining 2 insert calls so that latter depends on the id of the former. The id column is identity and gets created automatically.
How can I achieve this? Scheduled job is written in javascript/node.js. I have tried
var res = table1.insert(val1);
And using val1.id after the first insert, but neither works.
And of course just moments after I post the question I come up with an answer.
table1.insert(val1, {
success: function(res) {
var val2 = {
data: res.id
}
table2.insert(val2);
}
});
I am working on an interface that contains several high-intensity SQL queries, then renders multiple Google charts which are currently being called via AJAX using the google.visualization.Query object:
var query = new google.visualization.Query('/report.ashx');
query.send(callbackMethod);
//....
function callbackMethod(rs){
var data = rs.getDataTable();
var graph = new google.visualization.AreaChart(target_div);
graph.draw(data);
}
As the interface can be filtered dynamically I have encountered a scenario whereby a query can be running, whilst the user could potentially choose to re-filter and hence re-query the data source. If the first query is still running and the second query begins and returns before the first query then the chart will be drawn just fine. However, when the first query finally completes it could completely overwrite the chart with the old data, ignoring the current filters.
I have read that there is the ability to pass a jQuery AJAX object in, which exposes an XHR object allowing me to call .abort() on the XHR which would cancel the request (albeit this would still process on the server, but that's a hit I'm willing to take). Unfortunately I can find no examples of this and the Google documentation is less than helpful in this respect. Has anybody encountered the same, and if so - have they solved the problem?
Cheers,
Chris.
You can wrap callbackMethod in a higher order function to keep track of the request time, and use query.send(callback()) instead of query.send(callbackMethod).
var mostRecentReqTime;
var callback = function() {
var reqTime = Date();
return function() {
if (reqTime < mostRecentReqTime) return;
var data = rs.getDataTable();
var graph = new google.visualization.AreaChart(target_div);
graph.draw(data);
mostRecentReqTime = reqTime;
};
};
I need the number of facebook likes, which I get through
https://graph.facebook.com/?ids=http://www.stackoverflow.com
it is a json output:
{
"http://www.stackoverflow.com": {
"id": "http://www.stackoverflow.com",
"shares": 4984,
"comments": 2
}
}
But how to extract this number 4984 and to set a javascript variable to this number?
Please, show a small working example.
thanks
Graph API have support of JSONP, so you may use callback argument to call your function which will set the desired variable:
var likes;
function setLikes(data){
likes = data.shares;
console.log('Got results', data.id, likes);
}
var s = document.createElement('script');
s.src = 'https://graph.facebook.com/?id=http://www.stackoverflow.com&callback=setLikes';
document.getElementsByTagName('head')[0].appendChild(s);
Note: I've changed ids to id which is simplify output if you only need details for one OpenGraph object. If you need to get info for many objects you'll need to change a bit setLikes method to loop over keys or get info by desired key data['http://www.stackoverflow.com'].shares
Update:
Due to asynchronous nature of previous call you'll need to wait with code that depend on likes until getLikes called. This may be done in many ways, look to the next code to get some clue...
var likes; // This is a variable scoped outside of setLikes!
function setLikes(data){
// Once this is set likes will be available everywhere in the scope it defined!
likes = data.shares;
// You may run code that depends on likes variable here
call_function_that_depends_on_likes();
// You can also fire an event that your code subscribed to
// and pass likes as an argument...
// If you using Facebook JS-SDK
FB.Event.fire('my-custom-event', likes);
// If you using jQuery
$(document).trigger('my-custom-event', likes)
}
// If you using Facebook JS-SDK
FB.Event.subscribe('my-custom-event', function(likes){
// Run your code from here
});
// If you using jQuery
$(document).on('my-custom-event', function(evt, likes){
// Run your code from here
});
You've probably already done something similar if you used domready or document.load.
If you have that object in a variable output, you would read it like this:
var likes = output["http://www.stackoverflow.com"].shares;
But I gather that you also wonder how to retrieve that value from Facebook? Here is using the popular javascript library jQuery:
$.getJSON("https://graph.facebook.com/?ids=http://www.stackoverflow.com&callback=?", function(response) {
var likes = response["http://www.stackoverflow.com"].shares;
// Go do something with likes here
});