I have a enhancegrid which fields are editable. Some fields will be changed manually while others will change dynamically. The thing is that I would not want to store values onApplyEdit, I want to force save the values but I cant find the solution for it. Here is how it´s right now which actually working great.
dojo.connect(grid, "onApplyEdit", grid, function(evt, rowIndx, fieldIndx){
var selected_item = grid.getItem(evt);
//Not sure if this is the most efficient way but it worked for me
var row_id = grid.store.getValue(selected_item, "row_id");
var from_item_no = grid.store.getValue(selected_item, "from_item_no");
var from_inventory = grid.store.getValue(selected_item, "from_inventory");
var comment = grid.store.getValue(selected_item, "comment");
edit_quantity = grid.store.getValue(selected_item, "quantity");
var to_item_no = grid.store.getValue(selected_item, "to_item_no");
var to_inventory = grid.store.getValue(selected_item, "to_inventory");
var foundation = grid.store.getValue(selected_item, "foundation");
// Instantiate some write implementing store.
var store = grid.store;
// Set our load completed handler up...
var onCompleteFetch = function(items, request){
// Define the save callbacks to use
var onSave = function(){
dojo.xhrPost({
url: url,
content: {
row_id: row_id,
from_item_no: from_item_no,
from_inventory: from_inventory,
comment: comment,
quantity: edit_quantity,
to_item_no: to_item_no,
to_inventory: to_inventory,
foundation: foundation
},
handleAs: "text",
load: function(data){
console.log("Returned value: " + data);
global_saved_check = false;
},
error: function(error){
alert(error);
}
});// end xhrPost
} // end onSave
var onSaveError = function(error){
alert("Error occurred: " + error);
}
// If the store has modified items (it should), call save with the handlers above.
if(store.isDirty()){
store.save({onComplete: onSave, onError: onSaveError});
}
} // end onCompleteFetch
// Define a fetch error handler, just in case.
var onFetchError = function(error, request){
alert("Fetch failed. " + error);
}
// Fetch some data... All items with a foo attribute, any value.
store.fetch({query: {foo:"*"}, onComplete: onCompleteFetch});
});//end connect onApplyEdit
Related
I need help with this scenario, getting all data from multiple select tag
and use those data to send an API request.
I have these three select tags, and one button to send a request to a news API.
The user needs to select a value from those select tags to set data like "source" and "category".
Example: "https://xxxxxxxxxxxx.org/v2/top-headlines?source='+ source +' + '&category='+ cat +'&apiKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Not sure if this the efficient way.
Below is my js code.
//global variables
var apiUrl = 'https://xxxxxxxxxxxxxxxxxx',
apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxx',
displayRequest = document.querySelector('.displayRequestData'),
requestBtn = document.querySelector('#runApi'), //Btn to display data
newsOpt = document.querySelector('#news-selection'), //news select tag
catOpt = document.querySelector('#news-category'); //category select tag
requestBtn.addEventListener('click', newsRequest); //onclick
function sourceSelected() { //news option
var source = newsOpt !== null ? newsOpt.options[newsOpt.selectedIndex].value : 'the-next-web';
var cat = catOpt !== null ? catOpt.options[catOpt.selectedIndex].value : 'general';
return newsRequest(source, cat);
}
function newsRequest(source, cat) {
axios.get(apiUrl + 'top-headlines?sources=' + source + '&language=' + cat + '&apiKey=' + apiKey)
.then(function (response) {
var reStringify = JSON.stringify(response);
var rejson = JSON.parse(reStringify);
if (rejson.data.status == 'ok'){
console.log(rejson.data.articles[1].source.name);
//console.log(requestBtn);
}
})
.catch(function (error) {
console.log(error);
});
}
By the way, i got this error
VM7472:1 GET https://xxxxxxxxxxxxxxxxxxxxxxxx/v2/top-headlines?sources=[object%20MouseEvent]&language=undefined&apiKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxx 400 (Bad Request)
When you add the event listener to call newsRequest via onClick, the first and only parameter that will be sent to that function is the event object. Therefore, the parameters of source and cat are not passed to newsRequest when they click on the button. (This is why your resulting URL has the [object MouseEvent] in it)
Instead, you might want to call your sourceSelected function in the onClick event which is fetching the current field values and then calling the newsRequest function.
I play around with my code, it's working now.
Note: The news API I'm using not allowing me to mix some data like country, source and langauge. So I try things that only allowed for free account and it works.
requestBtn.addEventListener('click', sourceSelected); //onchange
function sourceSelected() { //news option
var source = newsOpt !== null ? newsOpt.options[newsOpt.selectedIndex].value : 'en';
var cat = catOpt !== null ? catOpt.options[catOpt.selectedIndex].value : 'general';
return newsRequest(source, cat);
} //end of sourceSelected
function newsRequest(source, cat) {
axios.get(apiUrl + 'top-headlines?country=' + source + '&category=' + cat + '&apiKey=' + apiKey)
.then(function (response) {
var reStringify = JSON.stringify(response);
var rejson = JSON.parse(reStringify);
if (rejson.data.status == 'ok') {
console.log(rejson.data.articles[1].source.name);
//console.log(requestBtn);
}
})
.catch(function (error) {
console.log(error);
});
}//newsRequest
I would like to test if the ajax request is identical so it can be aborted or some other alert action taken?
In reality clients can change the request via a few form elements then hit the refresh button.
I have made a poor attempt at catching the identical request. Need to keep the timer refresh functionality.
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
var current_request_id = 0;
var currentRequest = null;
var lastSuccessfulRequest = null;
function refreshTable() {
$('#select').html('Loading');
window.clearTimeout(timer);
//MY CATCH FOR DUPLICATE REQUEST NEEDS WORK
if (lastSuccessfulRequest == currentRequest)
{
//currentRequest.abort();
alert('Duplicate query submitted. Please update query before resubmission.');
}
var data = {
"hide_blanks": $("#hide_blanks").prop('checked'),
"hide_disabled": $("#hide_disabled").prop('checked'),
};
json_data = JSON.stringify(data);
current_request_id++;
currentRequest = $.ajax({
url: "/calendar_table",
method: "POST",
data: {'data': json_data},
request_id: current_request_id,
beforeSend : function(){
if(currentRequest != null) {
currentRequest.abort();
}
},
success: function(response) {
if (this.request_id == current_request_id) {
$("#job_table").html(response);
$("#error_panel").hide();
setFixedTableHeader();
}
},
error: function(xhr) {
if (this.request_id == current_request_id) {
$("#error_panel").show().html("Error " + xhr.status + ": " + xhr.statusText + "<br/>" + xhr.responseText.replace(/(?:\r\n|\r|\n)/g, "<br/>"));
}
},
complete: function(response) {
if (this.request_id == current_request_id) {
$("#select").html("Refresh");
window.clearTimeout(timer);
stopRefreshTable();
window.refreshTableTimer = window.setTimeout(refreshTable, 10000);
lastSuccessfulRequest = currentRequest;
}
}
});
}
//TIMER STUFF TO refreshTable()
//THIS SECTION WORKS FINE
var startDate = new Date();
var endDate = new Date();
var timer = new Date();
function startRefreshTable() {
if(!window.refreshTableTimer) {
window.refreshTableTimer = window.setTimeout(refreshTable, 0);
}
}
function stopRefreshTable() {
if(window.refreshTableTimer) {
self.clearTimeout(window.refreshTableTimer);
}
window.refreshTableTimer = null;
}
function resetActive(){
clearTimeout(activityTimeout);
activityTimeout = setTimeout(inActive, 300000);
startRefreshTable();
}
function inActive(){
stopRefreshTable();
}
var activityTimeout = setTimeout(inActive, 300000);
$(document).bind('mousemove click keypress', function(){resetActive()});
</script>
<input type="checkbox" name="hide_disabled" id="hide_disabled" onchange="refreshTable()">Hide disabled task<br>
<br><br>
<button id="select" type="button" onclick="refreshTable();">Refresh</button>
I'd use the power of .ajaxSend and .ajaxSuccess global handlers.
We'll use ajaxSuccess to store a cache and ajaxSend will try to read it first, if it succeeds it will trigger the success handler of the request immediately, and abort the request that is about to be done. Else it will let it be...
var ajax_cache = {};
function cache_key(settings){
//Produce a unique key from settings object;
return settings.url+'///'+JSON.encode(settings.data);
}
$(document).ajaxSuccess(function(event,xhr,settings,data){
ajax_cache[cache_key(settings)] = {data:data};
// Store other useful properties like current timestamp to be able to prune old cache maybe?
});
$(document.ajaxSend(function(event,xhr,settings){
if(ajax_cache[cache_key(settings)]){
//Add checks for cache age maybe?
//Add check for nocache setting to be able to override it?
xhr.abort();
settings.success(ajax_cache[cache_key(settings)].data);
}
});
What I've demonstrated here is a very naïve but functional approach to your problem. This has the benefit to make this work for every ajax calls you may have, without having to change them. You'd need to build up on this to consider failures, and to make sure that the abortion of the request from a cache hit is not getting dispatched to abort handlers.
One valid option here is to JSON.Stringify() the objects and compare the strings. If the objects are identical the resulting serialised strings should be identical.
There may be edge cases causing slight differences if you use an already JSONified string directly from the response so you'll have to double check by testing.
Additionally, if you're trying to figure out how to persist it across page loads use localStorage.setItem("lastSuccessfulRequest", lastSuccessfulRequest) and localStorage.getItem("lastSuccessfulRequest"). (If not, let me know and I'll remove this.)
I have a web application that performs a Jquery .post request for database queries. I also have three different web socket connections that are used to push status updates from the server to the client (CPU and Memory stats in a live chart, database status, and query queue). While a query is not running, everything works smoothly, but once a query is started (post request), then the three web socket connections seem to hang/block while waiting for the query to return. I was reading about this and have not found any relevant answers...I suspect that it is probably something really dumb on my part...but this has had me scratching my head for the better part of a day now. I thought I might try moving the web socket connections to web workers...but in theory, the POST should not be blocking to begin with...So, here are the relevant snippets of code...The full source is a couple of thousand lines of code...so I didn't want to inundate anyone with it...but could show it if it is useful. So, the big question is what am I doing wrong here? Or perhaps, am I misunderstanding how AJAX calls work as far as blocking goes?
// query execution button that grabs the query for the most recently focused query source (SPARQL editor, history, or canned)
$("#querySubmitButton").on("click", function(e) {
// Disable the query button
$("#querySubmitButton").attr('disabled',true);
// Let's make sure we are clearing out the work area and the popup contents
$("#viz").empty();
// Get YASQE to tell us what type of query we are running
var queryType = editor.getQueryType();
// refactored so that we can clean up the on-click function and also make other query types in a more modular way
switch(queryType) {
case 'SELECT':
sparqlSelect();
break;
case 'CONSTRUCT':
sparqlConstruct();
break;
case 'ASK':
sparqlAsk();
break;
case 'DESCRIBE':
sparqlDescribe();
break;
case 'INSERT':
sparqlInsert();
break;
default:
popup.show("Unrecognized query type.","error");
break;
}
});
// Functions to do each of the query types (SELECT, CONSTRUCT, ASK, DESCRIBE, INSERT)
// SELECT
function sparqlSelect() {
$.post("sparqlSelect", { database: $("#DB_label").html(),'query': editor.getValue() }).done(function(data, textStatus, xhr) {
// Enable the query button
$("#querySubmitButton").removeAttr('disabled');
// If the query worked, store it
storeQueryHistory(query);
// if the previous query was a CONSTRUCT, then lets hide the graph metrics button
$("#nav-trigger-graphStatistics").fadeOut(800);
// Need to slide the query menu back
sliders("in",$("#nav-trigger-query").attr("id"));
var columns = [];
var fields = [];
var comboboxFields = [];
// Hide the graph search panel
$("#graphSearch").fadeOut(1400);
// Show the results and visualization button/tab
$("#nav-trigger-results").fadeIn(1400);
$("#nav-trigger-visualization").fadeIn(1400);
$.each(data.results.head.vars, function(index, value) {
columns.push({'field': value, 'title': value});
var to = {};
to[value] = {type: "string"};
fields.push(to);
// Let's also populate the two Comboboxes for the Visualization while we are at it
comboboxFields.push({'text': value, 'value': value});
});
// Now, set the two combobox datasources for visualizations
var categoriesDS = new kendo.data.DataSource({
data: comboboxFields
});
vizCategoryAxis.setDataSource(categoriesDS);
var valuesDS = new kendo.data.DataSource({
data: comboboxFields
});
vizValueAxis.setDataSource(valuesDS);
var dataBindings = [];
$.each(data.results.results.bindings, function(index1, value) {
var tempobj = {};
$.each(value, function(k1,v1) {
tempobj[k1] = v1.value;
});
tempobj.id=index1;
dataBindings.push(tempobj);
});
var configuration = {
dataSource: {
data: dataBindings,
pageSize: 25
},
height: 400,
scrollable: true,
sortable: true,
filterable: true,
reorderable: true,
resizable: true,
toolbar: ["excel"],
excel: {
allPages: true,
filterable: true,
proxyURL: "/saveExcel"
},
pageable: {
input: true,
numeric: false,
pageSizes: true
},
'columns': columns,
dataBound: function(e) {
$(e.sender.element).find('td').each(function() {
var temp = $(this).html();
if (isUrl(temp)) {
$(this).html('' + temp + '');
}
});
}
};
// Create the popup window
var gridWindow = $("#resultsPopup").kendoWindow({
width: "70%",
title: "Query Results",
actions: [
"Minimize",
"Maximize",
"Close"
]
}).data('kendoWindow');
// Center and show the popup window
gridWindow.center().open();
// Create/update/refresh the grid
resultsGrid.setOptions(configuration);
resultsGrid.dataSource.page(1);
$("#nav-trigger-results").on('click',function() {
// Center and show the popup window
gridWindow.center().open();
});
}).fail(function(xhr) {
// If we are timed-out
if (xhr.status === 401) {
// First, clear the host, database, and status text
$("#host_label").html('');
$("#DB_label").html('');
$("#status_label").html('');
// Next, disable the query button
$("#querySubmitButton").attr('disabled',true);
// Change "login" tab text color to red so we know we are no longer logged in
var styles = { 'color': "#FFCCD2" };
$("#nav-trigger-login").css(styles);
popup.show("Session for " + host + " has timed out, please log back in.","error");
}
else {
// Enable the query button
$("#querySubmitButton").removeAttr('disabled');
popup.show("Error, no results (" + xhr.status + " " + xhr.statusText + ")","error");
}
});
}
// Function to connect to the query queue websocket
function queueWebsocketConnect() {
var qws = new WebSocket('wss://endeavour:3000/queue');
// Let's disconnect our Websocket connections when we leave the app
$(window).on('unload', function() {
console.log('Websocket connection closed');
qws.close();
});
// Status websocket onopen
qws.onopen = function () {
console.log('Websocket connection opened');
popup.show("Websocket connection opened","success");
};
qws.onclose = function (event) {
console.log('Websocket connection closed');
popup.show("Websocket connection closed","info");
};
qws.onmessage = function (msg) {
var res = JSON.parse(msg.data);
var tableRows = '<thead><tr><td>Query Position</td><td>Query ID</td><td>Kill/Cancel Query</td></tr></thead><tbody>';
if (res.executing != null && res.entry.length > 0) {
$("#queryQueue").empty();
tableRows += '<tr><td>1</td><td>' + res.executing.id + '</td><td><input type="button" class="k-button" value="Kill"></td></tr>';
$.each(res.entry, function(index,object) {
tableRows += '<tr><td>' + (object.pos + 1) + '</td><td>' + object.query.id + '</td><td><input type="button" class="k-button" value="Cancel"></td></tr>';
});
tableRows += '</tbody>';
$("#queryQueue").html(tableRows);
}
else if (res.executing != null) {
$("#queryQueue").empty();
tableRows += '<tr><td>1</td><td>' + res.executing.id + '</td><td><input type="button" class="k-button" value="Kill"></td></tr>';
tableRows += '</tbody>';
$("#queryQueue").html(tableRows);
}
else {
console.log(res);
$("#queryQueue").empty();
}
};
}
// Function to connect to the stats websocket
function websocketConnect () {
// Set up websocket connection for system stats
var ws = new WebSocket('wss://endeavour:3000/stats');
// Let's disconnect our Websocket connections when we leave the app
$(window).on('unload', function() {
console.log('Websocket connection closed');
ws.close();
});
// Status websocket onopen
ws.onopen = function () {
console.log('Websocket connection opened');
popup.show("Websocket connection opened","success");
};
// Status websocket onclose
ws.onclose = function (event) {
// Disable the query button
$("#querySubmitButton").attr('disabled',true);
// Change "login" tab text color to red so we know we are no longer logged in
var styles = { 'color': "#FFCCD2" };
$("#nav-trigger-login").css(styles);
// Clear the host, database, and status text
$("#host_label").html('');
$("#DB_label").html('');
$("#status_label").html('');
console.log('Websocket connection closed');
popup.show("Websocket connection closed","error");
$("#websocketReconnectButtonYes").on('click', function() {
websocketConnect();
queueWebsocketConnect();
websocketReconnect.close();
});
$("#websocketReconnectButtonNo").on('click', function() {
websocketReconnect.close();
});
websocketReconnect.center().open();
};
// When updates are received, push them out to update the details
var logoutCount = 0;
ws.onmessage = function (msg) {
if (msg.data === 'loggedOut') {
// Ensure we only emit this one time instead of a stream of them
if (logoutCount == 0) {
// Disable the query button
$("#querySubmitButton").attr('disabled',true);
// Change "login" tab text color to red so we know we are no longer logged in
var styles = { 'color': "#FFCCD2" };
$("#nav-trigger-login").css(styles);
// Clear the host, database, and status text
$("#host_label").html('');
$("#DB_label").html('');
$("#status_label").html('');
console.log("Session for " + $("#host_label").html() + " has timed out, please log back in.");
popup.show("Session for " + $("#host_label").html() + " has timed out, please log back in.","error");
}
logoutCount = 1;
}
else {
logoutCount = 0;
var res = JSON.parse(msg.data);
var host = $("#host_label").html();
var pdatabase = $("#DB_label").html();
var pstatus = $("#status_label").html();
// Disable the query button unless the database is "CONNECTED"
if ($("#status_label").html() !== res.current.databaseStatus) {
if (res.current.databaseStatus !== "CONNECTED") {
$("#querySubmitButton").attr('disabled',true);
}
else {
$("#querySubmitButton").removeAttr('disabled');
}
if (res.current.databaseStatus == 'CONNECTED' || res.current.databaseStatus == 'STOPPED') {
$("#startDB").removeAttr('disabled');
}
else {
$("#startDB").attr('disabled',true);
}
}
// Maybe a more intelligent way to do this, but need to make sure that if the cookie is still valid, then populate the database login stuff
if ($("#dbConfigHost").val() == "" && $("#dbConfigUser").val() == "") {
$("#dbConfigHost").val(res.host);
$("#dbConfigUser").val(res.user);
// Change "login" tab text color to green so we know we are logged in
var styles = { 'color': "#C5E6CC" };
$("#nav-trigger-login").css(styles);
var databasesDS = new kendo.data.DataSource({
data: res.databases.database
});
databasePicker.setDataSource(databasesDS);
}
// Update the labels when values change
if (res.host != $("#host_label").html()) {
$("#host_label").html(res.host);
popup.show("Host changed to " + res.host,"info");
}
if (pdatabase != res.current.name) {
$("#DB_label").html(res.current.name);
popup.show("Database changed to " + res.current.name ,"info");
}
if (pstatus != res.current.databaseStatus) {
$("#status_label").html(res.current.databaseStatus);
}
// Update the sparklines
cpulog.options.series[0].data = res.system.cpu;
cpulog.refresh();
memlog.options.series[0].data = res.system.mem;
memlog.refresh();
}
};
// Open the websocket connection to listen for changes to the query list
var queryWS = new WebSocket('wss://endeavour:3000/queryList');
queryWS.onmessage = function(msg) {
var res = JSON.parse(msg.data);
var queriesDS = new kendo.data.DataSource({
data: res
});
cannedQuery.setDataSource(queriesDS);
};
}
Well, I guess when one has been heading down one road for a while, one assumes that it is in the right direction. After further head-scratching, I found the issue and it was related to the blocking/non-blocking nature of my backend web-framework. As it turns out, in Mojolicious (Perl web-framework), http calls can be either synchronous or asynchronous depending on how one writes the call.
my $tx = $ua->get('http://foo.bar?query=getSomeFoo');
if($tx->success) {
$self->render($tx->res->content);
}
else {
$self->rendered($tx->res->code);
}
This is a blocking/synchronous request. Nothing happens until after the GET finishes. On the other hand, if one writes the request like so, it is an asynchronous request:
$ua->get('http://foo.bar?query=getSomeFoo' => sub {
my ($ua,$tx) = #_;
if($tx->success) {
$self->render($tx->res->content);
}
else {
$self->rendered($tx->res->code);
}
});
So, if anyone else has encountered this issue...here is the answer. If I am the only idiot on the planet that has committed this blunder...then I guess I have put my shame out there for all to have a good chuckle at.
Bottom line was that this was well documented in the Mojolicious docs...but I had been doing it one way for so long that I completely forgot about it.
Cheers!
Using parse.com and JavaScript SDK.
I've searched, but cannot find a good answer for this.
This function works when I use just use current user. However what it should do is use the value stored in the variable friendRequest to query results that already exist in parse. The FriendRequest variable is populated once the user clicks on one of the images being displayed on the page within the div id container
I get the following error and I'm not sure how to fix it? Is it because FriendRequest is undefined?
Uncaught Error: Can't serialize an unsaved Parse.Object
Screen shot attached.
Here is the function returning the error.
function FriendProfile() {
var FriendRequest = Parse.Object.extend("FriendRequest");
var friendRequest = new FriendRequest();
friendRequest.id = window.selectedFriendRequestId;
var myBadges = Parse.Object.extend("myBadges");
var query = new Parse.Query(myBadges);
query.equalTo("SentTo", friendRequest);
query.find({
success: function (results) {
// If the query is successful, store each image URL in an array of image URL's
imageURLs = [];
for (var i = 0; i < results.length; i++) {
var object = results[i];
imageURLs.push(object.get('BadgeName'));
}
// If the imageURLs array has items in it, set the src of an IMG element to the first URL in the array
for (var j = 0; j < imageURLs.length; j++) {
$('#imgs').append("<img src='" + imageURLs[j] + "'/>");
}
},
error: function (error) {
// If the query is unsuccessful, report any errors
alert("Error: " + error.code + " " + error.message);
}
});
}
Here is how the friendRequest variable is populated .
var currentUser = Parse.User.current();
var FriendRequest = Parse.Object.extend("FriendRequest");
var query = new Parse.Query(FriendRequest);
query.include('toUser');
query.include("myBadge");
query.equalTo("fromUser", currentUser);
query.equalTo("status", "Request sent");
query.find({
success: function (results) {
var friends = [];
for (var i = 0; i < results.length; i++) {
friends.push({
imageURL: results[i].get('toUser').get('pic'),
friendRequestId: results[i].id,
username: results[i].get('toUser').get('username')
});
}
// TW: replaced dynamic HTML generation with wrapper DIV that contains IMG and name DIV
_.each(friends, function (item) {
// using a wrapper so the user can click the pic or the name
var wrapper = $('<div class="wrapper" data-friend-request-id="' + item.friendRequestId + '"></div>');
wrapper.append('<img class="images" src="' + item.imageURL + '" />');
wrapper.append('<div>' + item.username + '</div>');
$('#container').append(wrapper);
});
},
error: function (error) {
alert("Error: " + error.code + " " + error.message);
}
});
///SECTION 2 -Click/Select friend image to be captured and used with section 3//////////
// set up event handler
$('#container').on('click', '.wrapper', function () {
console.log(this);
FriendProfile();
var wrapper = $(this);
console.log(wrapper.data('friendRequestId'));
// remove selected from all wrappers in case one was already selected
$('#container .wrapper').removeClass('selected');
// mark clicked wrapper as selected
wrapper.addClass('selected');
// save friendRequestId as a global that can be read by other code
window.selectedFriendRequestId = wrapper.data('friendRequestId');
// enabled button
$('#simulateAddBadge').removeAttr('disabled');
});
$(document).ready(function () {
$('.go').css('cursor', 'pointer');
$('.go').click(function (e) { // Button which will activate our modal
$(this).width(100).height(100).appendTo('#badgeselect');
});
return false;
});
If window.selectedFriendRequestId is not set when FriendProfile() is called, then you will get an error. Add console.log(window.selectedFriendRequestId); in there to help you debug.
You need to examine the logic you are after, you might instead want to make the friendRequestId a parameter of the function and extract the value in the click handler and pass it as a parameter. Currently your "SECTION 2" code is calling the function then setting the value afterwards.
Simplified example:
function FriendProfile(friendRequestId) {
// query based on friendRequestId ...
}
// other code that calls function
$('#container').on('click', '.wrapper', function () {
var wrapper = $(this);
var friendRequestId = wrapper.data('friendRequestId');
FriendProfile(friendRequestId);
// other code ...
});
I am trying to explicitly get the system properties from my table but it is not working. I can see that the URL is returning all the data including these fields if I use https://myservice.azure-mobile.net/tables/todoitem?__systemProperties=* but on the code I cannot get it as item.__version or item.version. I have tried adding todoitemtable = WindowsAzure.MobileServiceTable.SystemProperties.All; but no success! I have also looked at http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-validate-modify-data-server-scripts/ but this is adding a new column instead of using the existing system columns.
$(function() {
var client = new WindowsAzure.MobileServiceClient('https://ib-svc-01.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
// = WindowsAzure.MobileServiceTable.SystemProperties.All;
// Read current data and rebuild UI.
// If you plan to generate complex UIs like this, consider using a JavaScript templating library.
function refreshTodoItems() {
var query = todoItemTable.where({ complete: false });
query.read().then(function(todoItems) {
var listItems = $.map(todoItems, function(item) {
return $('<li>')
.attr('data-todoitem-id', item.id)
.append($('<button class="item-delete">Delete</button>'))
.append($('<input type="checkbox" class="item-complete">').prop('checked', item.complete))
.append($('<div>').append($('<input class="item-text">').val(item.id))
.append($('<span class="timestamp">'
+ (item.createdAt && item.createdAt.toDateString() + ' '
+ item.createdAt.toLocaleTimeString() || '')
+ '</span>')));
});
$('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
$('#summary').html('<strong>' + todoItems.length + '</strong> item(s)');
}, handleError);
}
function handleError(error) {
var text = error + (error.request ? ' - ' + error.request.status : '');
$('#errorlog').append($('<li>').text(text));
}
function getTodoItemId(formElement) {
return $(formElement).closest('li').attr('data-todoitem-id');
}
// Handle insert
$('#add-item').submit(function(evt) {
var textbox = $('#new-item-text'),
itemText = textbox.val();
if (itemText !== '') {
todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems, handleError);
}
textbox.val('').focus();
evt.preventDefault();
});
// Handle update
$(document.body).on('change', '.item-text', function() {
var newText = $(this).val();
todoItemTable.update({ id: getTodoItemId(this), text: newText }).then(null, handleError);
});
$(document.body).on('change', '.item-complete', function() {
var isComplete = $(this).prop('checked');
todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems, handleError);
});
// Handle delete
$(document.body).on('click', '.item-delete', function () {
todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems, handleError);
});
// On initial load, start by fetching the current data
refreshTodoItems();
});
I was trying to access the system properties from within the API scripts and found this and thought it was useful and relevant: http://www.brandonmartinez.com/2014/10/22/retrieve-system-properties-in-azure-mobile-services-javascript-backend/
Basically you can do this (example from the post):
myTable.read({
systemProperties: ['__createdAt', '__updatedAt'],
success: function(tableEntries) {
// So on and so forth
}
}