Return string from second function - javascript

Well i have created a function to return the picture url. See code below:
function loadAttachment(itemid) {
web = context.get_web();
attachmentFolder = web.getFolderByServerRelativeUrl("Lists/LijstMedewerkers/Attachments/" + itemid);
attachmentFiles = attachmentFolder.get_files();
//Load attachments
context.load(attachmentFiles);
context.executeQueryAsync(onLoaddAttachmentSuccess, onLoadAttachmentFail);
alert(picture);
return picture;
}
function onLoadAttachmentFail(sender, args) {
alert('Failed to get lists items. Error:' + args.get_message());
}
function onLoaddAttachmentSuccess(sender, args) {
// Enumerate and list the Asset Attachments if they exist
var attachementEnumerator = attachmentFiles.getEnumerator();
while (attachementEnumerator.moveNext()) {
var attachment = attachementEnumerator.get_current();
picture = attachment.get_serverRelativeUrl();
}
}
Well it's not returning the value of the picture. When i do an alert i see the value but with the return it's not working. even if i put the picture in the itemid.
Any idea what i'm doing wrong ?

Since SP.ClientContext.executeQueryAsync method is async:
SP.ClientContext.executeQueryAsync(succeededCallback, failedCallback)
succeededCallback is used for declaring 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
The below example demonstrates how to retrieve attachment files using callback approach:
function loadAttachments(listTitle, itemId,success,error) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(listTitle);
var listItem = list.getItemById(itemId);
var files = listItem.get_attachmentFiles();
context.load(files);
context.executeQueryAsync(function(){
success(files);
},
error);
}
Usage
Get first file attachment url
loadAttachments('Projects',3,
function(attachmentFiles){
if(attachmentFiles.get_count() > 0) {
var attachmentFile = attachmentFiles.getItemAtIndex(0);
var fileUrl = attachmentFile.get_serverRelativeUrl();
//...
}
},
function(sender,args){
console.log(args.get_message());
});

Related

uilocations is declared but its value is never read

I'm building a price prediction model using Python, Flask Server, HTML, and CSS. I've implemented the HTML and CSS code but I'm having issues getting my dropdown button to read all my locations via a JavaScript call (all the locations are saved in a json file). Concerning 'uilocations' it keeps showing 'uilocations is declared but its value is never read. Below is my javascript code:
function onClickedEstimatedPrice(){
var uiBathrooms = document.getElementsByName("uiBathrooms");
for(var i in uiBathrooms) {
if(uiBathrooms[i].checked) {
return parseInt(i)+1;
}
}
return -1;
}
function getBHKValue() {
var uiBHK = document.getElementsByName("uiBHK");
for(var i in uiBHK) {
if(uiBHK[i].checked) {
return parseInt(i)+1;
}
}
return -1; // The above functions iterate through the buttons and return the values
}
function onClickedEstimatedPrice() {
console.log("Estimated price button clicked");
var sqft = document.getElementById("uilocations");
var bathrooms = document.getElemenbtById("uiEstimatedPrice");
var estPrice = document.getElementById("uiEstimatedPrice")
var url = "http://127.0.0.1:5000/predict_home_price"; //url for the price prediction endpoint
$.post(url, { //This is a jquery POST call that makes a POST call to the url, we will get our output back in 'data'
total_sqft: parseFloat(sqft.value),
bhk: bhk,
bath: bathrooms,
location: location.value
},function(data, status) {
console.log(data.estimated_price);
estPrice.innerHTML = "<h2>" + data.estimated_price.toString() + " Lakh</h2>";
console.log(status)
}
)
}
function onPageLoad() {
console.log( "document loaded" );
var url = "http://127.0.0.1:5000/get_location_names"; //Here we make our HTTP Call
$.get(url,function(data, status) { //This is a jquery GET call that makes a GET call to the url, we will get our response back in the 'data'
console.log("got response for get_location_names request");
if(data) {
var locations = data.locations; //This will be our list of locations
var uilocations = document.getElementById("uilocations");
$("#uilocations").empty();
for(var i in locations) {
var opt = new Option(locations[i]);
$("#uilocations").append(opt);
} //The above goes through our locations one by one and adds them to our dropdown
}
});
}
window.onload = onPageLoad; //This will be used to load our HTML page and load the locations
I tried the code above, i expected my dropdown button to pick more locations but whenever i refresh the page on my browser, i don't get the expected output

ServiceNow UI Page GlideAjax

I created a form using UI Page and am trying to have some fields autopopulated onChange. I have a client script that works for the most part, but the issue arises when certain fields need to be dot-walked in order to be autopopulated. I've read that dot-walking will not work in client scripts for scoped applications and that a GlideAjax code will need to be used instead. I'm not familiar with GlideAjax and Script Includes, can someone help me with transitioning my code?
My current client script looks like this:
function beneficiary_1(){
var usr = g_user.userID;
var related = $('family_member_1').value;
var rec = new GlideRecord('hr_beneficiary');
rec.addQuery('employee',usr);
rec.addQuery('sys_id',related);
rec.query(dataReturned);
}
function dataReturned(rec){
//autopopulate the beneficiary fields pending on the user selection
if(rec.next()) {
$('fm1_ssn').value = rec.ssn;
$('fm1_address').value = rec.beneficiary_contact.address;
$('fm1_email').value = rec.beneficiary_contact.email;
$('fm1_phone').value = rec.beneficiary_contact.mobile_phone;
var dob = rec.date_of_birth;
var arr = dob.split("-");
var date = arr[1] + "/"+ arr[2] + "/" + arr[0] ;
$('fm1_date_of_birth').value = date;
}
}
fm1_address, fm1_email, and fm1_phone do not auto populate because the value is dot walking from the HR_Beneficiary table to the HR_Emergency_Contact table.
How can I transform the above code to GlideAjax format?
I haven't tested this code so you may need to debug it, but hopefully gets you on the right track. However there are a couple of steps for this.
Create a script include that pull the data and send a response to an ajax call.
Call this script include from a client script using GlideAjax.
Handle the AJAX response and populate the form.
This is part of the client script in #2
A couple of good websites to look at for this
GlideAjax documentation for reference
Returning multiple values with GlideAjax
1. Script Include - Here you will create your method to pull the data and respond to an ajax call.
This script include object has the following details
Name: BeneficiaryContact
Parateters:
sysparm_my_userid - user ID of the employee
sysparm_my_relativeid - relative sys_id
Make certain to check "Client callable" in the script include options.
var BeneficiaryContact = Class.create();
BeneficiaryContact.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getContact : function() {
// parameters
var userID = this.getParameter('sysparm_my_userid');
var relativeID = this.getParameter('sysparm_my_relativeid');
// query
var rec = new GlideRecord('hr_beneficiary');
rec.addQuery('employee', userID);
rec.addQuery('sys_id', relativeID);
rec.query();
// build object
var obj = {};
obj.has_value = rec.hasNext(); // set if a record was found
// populate object
if(rec.next()) {
obj.ssn = rec.ssn;
obj.date_of_birth = rec.date_of_birth.toString();
obj.address = rec.beneficiary_contact.address.toString();
obj.email = rec.beneficiary_contact.email.toString();
obj.mobile_phone = rec.beneficiary_contact.mobile_phone.toString();
}
// encode to json
var json = new JSON();
var data = json.encode(obj);
return data;
},
type : "BeneficiaryContact"
});
2. Client Script - Here you will call BeneficiaryContact from #1 with a client script
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var usr = g_user.userID;
var related = $('family_member_1').value;
var ga = new GlideAjax('BeneficiaryContact'); // call the object
ga.addParam('sysparm_name', 'getContact'); // call the function
ga.addParam('sysparm_my_userid', usr); // pass in userID
ga.addParam('sysparm_my_relativeid', related); // pass in relative sys_id
ga.getXML(populateBeneficiary);
}
3. Handle AJAX response - Deal with the response from #2
This is part of your client script
Here I put in the answer.has_value check as an example, but you may want to remove that until this works and you're done debugging.
function populateBeneficiary(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
answer = answer.evalJSON(); // convert json in to an object
// check if a value was found
if (answer.has_value) {
var dob = answer.date_of_birth;
var arr = dob.split("-");
var date = arr[1] + "/"+ arr[2] + "/" + arr[0];
$('fm1_ssn').value = answer.ssn;
$('fm1_address').value = answer.address;
$('fm1_email').value = answer.email;
$('fm1_phone').value = answer.mobile_phone;
$('fm1_date_of_birth').value = date;
}
else {
g_form.addErrorMessage('A beneficiary was not found.');
}
}

Passing parameter to json_callback function

I am using an inverse geolocation method from mapquest that looks something like this
function fieldVia_changed(a)
{
if (document.getElementsByName("via"+a)[0].value.trim().length!=0)
{
var via = document.getElementsByName("via"+a)[0].value ;
var strV = via.replace(/ |,/g, "+");
var s = document.createElement('script');
s.src = 'http://open.mapquestapi.com/nominatim/v1/search?q='+strV+'&json_callback=cbv&format=json&polygon=1&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
}
}
The results of the request are processed in the function cbv which accepts a parameter
function cbv(json)
{
v_lat[0] = json[0].lat;
v_lng[0] = json[0].lon;
}
However i need to be able to pass another parameter to the cbv function from fieldVia_changed function so that i can process the information properly. The cbv function definition would look like this function cbv(json,a). I looked all over but i can not find a solution. Is it possible ?
The server side won't usually have the option of passing additional arguments in a JSONP system. A possible solution is to use the value of a in the callback function name, and dynamically create the function as a kind of man in the middle between the cbv() function, allowing you to pass a as a second argument.
function fieldVia_changed(a) {
if (document.getElementsByName("via" + a)[0].value.trim().length != 0) {
// dynamically create the function
window['cbv_' + a] = function (json) {
cbv(json, a);
};
var via = document.getElementsByName("via" + a)[0].value;
var strV = via.replace(/ |,/g, "+");
var s = document.createElement('script');
// call the function cbv_x
s.src = 'http://open.mapquestapi.com/nominatim/v1/search?q=' + strV + '&json_callback=cbv_' + a + '&format=json&polygon=1&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
}
}
function cbv(json, a) {
v_lat[0] = json[0].lat;
v_lng[0] = json[0].lon;
console.log(a);
}
This is OK if a is some sort of short identifier, if it's from user input then it's not really suitable for use in the function name. You're using in the name attributes so I'm assume this is fine.

Javascript and jQuery: accessing class member variables from event callback

I am writing a Javascript SDK to interact with a web service. I am using jQuery to do my AJAX calls.
When an AJAX call fails, I have registered an event handler for the ajaxError that gets called at the top of my .js file. My problem, and I don't understand why, is that when it gets called I have no way of accessing class member variables for my Akamanda.Client.
I tried adding another method for Akamanda.Client as .prototype.logError, which got called by the jQuery Ajax handler, but even then a test for (this.logging) failed as well.
How can I access class member variables from jQuery callbacks? What am I failing to understand here? Akamanda.Client.logging is undefined from the ajaxError callback.
My code for the SDK:
$(document).ajaxError(function(event, jqxhr, settings, exception) {
// more robust error handling for different conditions
if (Akamanda.Client.logging) {
console.log('FAILED: ' + settings.type + ' ' + settings.url + ' => ' + exception);
}
});
Akamanda.Client = function(options) {
this.URL = options.URL || 'http://m-test.akamanda.com';
this.baseURL = this.URL + '/api/' + Akamanda.API_VERSION;
this.feedsURI = '/websyndication/feed/';
// who is the client? (iphone/android/web)
this.clientName = options.clientName;
// For development: Logging and buildcurl IS ON, for production: OFF
//this.logging = options.logging || true;
this.logging = true;
// called when a user is not authorised (Disabled)
// this.logoutCallback = options.logoutCallback || null;
}
Akamanda.Client.prototype.getFeeds = function(callback){
var feeds = [];
$.getJSON(this.baseURL + this.feedsURI, function(data) {
$.each(data, function(index, feed) {
feeds[index] = {
name: feed.name,
title: feed.title,
link: feed.link
};
})
callback(feeds);
});//.error(function(err) { (disabled at the moment in favour of ajaxError event)
// console.log('Error: ' + err.error);
// });
}
My code for the client (in another JS source file):
var options = { logging: true };
myAPI = new Akamanda.Client(options);
var feeds = [];
var articles = [];
function getFeeds()
{
myAPI.getFeeds(function(AkamandaFeeds) {
feeds = AkamandaFeeds;
showFeeds();
});
}
As far as I can see from the code you posted, you are never instantiating an object of type Akamanda.Client.
var Client = new Akamanda.Client();
or
var Akamanda.Client = {};
Akamanda.Client.logging = ....
JSBin Example: http://jsbin.com/ajidig/1/edit
Ok, here a little example(real code but very simplified):
//we wrap our code in a self invoking function so that we don't pollute the global namespace, see http://stackoverflow.com/questions/6715805/self-invoking-functions-javascript for further details
(function(){
//create your object that holds all your function, that are different ways to do this
var Akamanda = {};
//a private function
function ErrorHandler(clientObj) {
this.clientObj = clientObj;
//do whatever with clientObj
this.log = function(){..}
}
//private constructor for clientobj
function Client(options){
..
}
Akamanda.Client = function(){
var newClient = new Client({..});
//setup
Akamanda.ErrorLogging = new ErrorHandler(newClient);
return newClient;
}
//bind our service to the window object to make it accesible
window.Akamanda = Akamanda;
})()
//client
var myAPI = Akamanda.Client();
Akamanda.ErrorLogging.log();
I hope this basic examples helps. If you need to know more about Javascript Patterns, I can recommend this book http://jsninja.com/ by John Resig, the creator of jQuery.
Depending on what you want to do, there's also a lot of frameworks like http://backbonejs.org/ that help with this kind of stuff.

Accessing Data from JavaScript Object's Array Member Variable

I'm writing a jQuery plugin for work which pulls in RSS feed data using Google's Feed API. Using this API, I'm saving all of the relevant RSS feed data into an object, then manipulating it through methods. I have a function which is supposed to render the RSS feed onto the webpage. Unfortunately, when I try to display the individual RSS feed entries, I get an error. Here's my relevant code:
var RSSFeed = function(feedTitle, feedUrl, options) {
/*
* An object to encapsulate a Google Feed API request.
*/
// Variables
this.description = "";
this.entries = [];
this.feedUrl = feedUrl;
this.link = "";
this.title = feedTitle;
this.options = $.extend({
ssl : true,
limit : 4,
key : null,
feedTemplate : '<article class="rss-feed"><h2>{title}</h1><ul>{entries}</ul></article>',
entryTemplate : '<li><h3>{title}</h3><p>by: {author} # {publishedDate}</p><p>{contentSnippet}</p></li>',
outputMode : "json"
}, options || {});
this.sendFeedRequest = function() {
/*
* Makes the AJAX call to the provided requestUrl
*/
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
// Save the data in a temporary object
var responseDataFeed = data.responseData.feed;
// Now load the data into the RSSFeed object
self.description = responseDataFeed.description;
self.link = responseDataFeed.link;
self.entries = responseDataFeed.entries;
});
};
this.display = function(jQuerySelector) {
/*
* Displays the RSSFeed onto the webpage
* Each RSSEntry will be displayed wrapped in the RSSFeed's template HTML
* The template markup can be specified in the options
*/
var self = this;
console.log(self);
console.log(self.entries);
};
};
$.rssObj = function(newTitle, newUrl, options) {
return new RSSFeed(newTitle, newUrl, options);
};
// Code to call the jquery plugin, would normally be found in an index.html file
rss = $.rssObj("Gizmodo", "http://feeds.gawker.com/Gizmodo/full");
rss.sendFeedRequest();
rss.display($('div#feed'));
Obviously, my display() function isn't complete yet, but it serves as a good example. The first console.log() will write all of the relevant data to the console, including the entries array. However, when I try to log the entries array by itself, it's returning an empty array. Any idea why that is?
I guess the problem is that display() is called without waiting for the AJAX request to complete. So the request is still running while you already try to access entries - hence the empty array.
In order to solve this you could move the call to display() into the callback of $.getJSON(). You just have to add the required selector as a parameter:
this.sendFeedRequest = function(selector) {
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
var responseDataFeed = data.responseData.feed;
...
self.entries = responseDataFeed.entries;
self.display(selector);
});
};
EDIT:
If you don't want to move display() into the callback, you could try something like this (untested!):
var RSSFeed = function(feedTitle, feedUrl, options) {
...
this.loading = false;
this.selector = null;
this.sendFeedRequest = function() {
var self = this;
self.loading = true;
$.getJSON(this.encodeRequest(), function(data) {
...
self.loading = false;
if (self.selector != null) {
self.display(self.selector);
}
});
};
this.display = function(jQuerySelector) {
var self = this;
if (self.loading) {
self.selector = jQuerySelector;
}
else {
...
}
};
};

Categories

Resources