How do I use JSON data? - javascript

When I query a server I get a JSON file in return. The JSON file I get back would be in the following format.
{
"head": {
"link": [],
"vars": ["bookName", "author"]
},
"results": {
"distinct": false,
"ordered": true,
"bindings": [
{
"bookName": {
"type": "literal",
"xml:lang": "en",
"value": "Of Mice and Men"
},
"author": {
"type": "literal",
"xml:lang": "en",
"value": "John Steinbeck"
}
}
]
}
}
This is what I have done so far:
$.ajax({
dataType: "jsonp",
url: queryUrl,
success: function(data) {
// get the table element
var table = $("#results");
// get the sparql variables from the 'head' of the data.
var headerVars = data.head.vars;
// using the vars, make some table headers and add them to the table;
var trHeaders = getTableHeaders(headerVars);
table.append(trHeaders);
// grab the actual results from the data.
var bindings = data.results.bindings;
var book = data.results.bindings[1].bookName.value;
// for each result, make a table row and add it to the table.
var numberOfBooks = 0;
for(rowIdx in bindings){
table.append(getTableRow(headerVars, bindings[rowIdx]));
numberOfBooks++;
}
document.getElementById("searched-for").innerHTML="<h1>You seach for " + '"' + input + '"' + " and we found " + numberOfBooks + " books </h1>";
}
});
What I want to be able to do is something like this:
var book = data.results.binding[1].bookName.value;

Try this:
$.ajax({
dataType: "jsonp",
url: queryUrl,
success: function(data) {
// get the table element
var table = $("#results");
// get the sparql variables from the 'head' of the data.
var headerVars = data.head.vars;
// using the vars, make some table headers and add them to the table;
var trHeaders = getTableHeaders(headerVars);
table.append(trHeaders);
// grab the actual results from the data.
var bindings = data.results.bindings;
var book;
if(bindings && bindings.length) {
book = bindings[0].bookName.value;
}
// for each result, make a table row and add it to the table.
var numberOfBooks = 0;
for(rowIdx in bindings){
table.append(getTableRow(headerVars, bindings[rowIdx]));
numberOfBooks++;
}
document.getElementById("searched-for").innerHTML="<h1>You seach for " + '"' + input + '"' + " and we found " + numberOfBooks + " books </h1>";
}
});
But that will only get the first book, if it exists.

Related

Processing Ajax Data Using External Function Results in Error

I have an Ajax function below which returns data. I can log data to the console, but I want to process the "skilllist" in a separate function to generate HTML to add to the overall string. The function returns the HTML, but when it does so it generates an error just because the function is called.
My AJAX function looks like:
$("#search").click(function() {
$.ajax({
type: "POST",
dataType: "json",
url: "/search/projectsearchsimple/",
data: { csrfmiddlewaretoken:'{{ csrf_token }}',
search : $("#id_search").val() },
success: function(data) {
//update_messages(data.messages);
console.log(data);
$("#resultsarea").show();
$("#resultspanel").empty();
data = JSON.parse(data);
var resultshtml = "";
for(i=0;i<data.length;i++) {
var skilllist = [...data[i].skilllist];
var skillsbox = createSkillsBox(skilllist);
resultshtml = resultshtml + "<div class='row'><div class='col-2'>" +
"<a href='/project/projectpage/" + data[i].id + "'>" +
data[i].name + "</a>" + "</div>" + "<div class='col-2'>by " +
data[i].owner__username + "</div><div class='col-3'>Created on: " +
data[i].created + "</div></div>";
}
$("#resultspanel").append(resultshtml);
}
});
});
The external function looks as:
function createSkillsBox(skills) {
skillsboxhtml = "<div class='menu-outer'><div class='table'><ul id='skills{{ job.id }}' class='horizontal-list skillsboxuser'>";
for(i=0;i<skills.length;i++) {
skillsboxhtml += "<li><strong>" + skills[i] + "</strong></li>"
}
skillsboxhtml += "</ul></div></div>";
return skillsboxhtml;
}
The error received in the console sates "TypeError: data[i] is undefined[Learn More]". If I comment out the line "var skillsbox = createSkillsBox(skilllist);" it works doesn't error.
The data variable contains:
[{"skilllist": ["Programming", "Musician", "Writing"], "name": "Project KFC", "id": 3, "owner__username": "kyle", "created": "18/11/19 10:00", "description": "description"}]
I have tried moving the function to inside the Ajax method and I have tried with passing data[i] direct before i tried the shallow copy.
Can anyone help?

Match key/values in JSON object

I have a school project where we are learning JSON. What I am trying to do is figure out how I can match keys with other keys that exist in another object property.
I'm using an old api to pull nfl player information. Here is an example of the url to pull the data:
http://api.fantasy.nfl.com/v1/players/stats?statType=seasonStats&season=2018&week=16&format=json
I'm using AJAX to call the data and stringify the results into a table.
$.ajax({
url: queryURL,
method: "GET"
}).then(function(response) {
var tbl = $("<table>");
$(tbl).addClass("table");
var objCount = JSON.stringify(response.players.length);
$(tbl).append("<thead><tr><th>ID</th><th>Team</th><th>POS</th>
<th>Player</th><th>Stat</th></tr></thead><tbody>");
for (p = 1; p < 2; p++) {
var id = response.players[p].id;
var team = response.players[p].teamAbbr;
var pos = response.players[p].position;
var plyr = response.players[p].name;
var stat = JSON.stringify(response.players[p].stats);
var plyrStatsObjLen =
JSON.stringify(response.players[p].stats.length);
console.log("statObjLength: " + plyrStatsObjLen);
$.each(response.players[p].stats, function(key, value) {
console.log(key + ": " + value);
});
$(tbl).append("<tr><td>" + id + "</td><td>" + team + "</td><td>" + pos + "</td><td>" + plyr + "</td><td>" + stat + "</td>");
}
$(tbl).append("</tbody><br/><br/>");
$("#statOutput").append(tbl);
});
Here is a fiddle of what I am doing:
https://jsfiddle.net/kenneth2k1/kcf5duLr/
If you notice the results, I have the stats property separated out in its own column, but it is still in the object's key/value structure.
Now, here is another url that has what each stat is:
https://api.fantasy.nfl.com/v1/game/stats?format=json
"stats": [
{
"id": 1,
"abbr": "GP",
"name": "Games Played",
"shortName": "GP"
},
{
"id": 2,
"abbr": "Att",
"name": "Passing Attempts",
"shortName": "Pass Att"
},
{
"id": 3,
"abbr": "Comp",
"name": "Passing Completions",
"shortName": "Pass Comp"
}, ... and so on
So for example key ID "1" corresponds with "Games Played" from the stat reference object.
I am new to all this, so what I can't wrap my head around is if I wanted to sub out the keys in my output with the corresponding name value from the stats reference object, how would I do that?
For example from the jsfiddle output, Instead of
{"1":"9","13":"1"}
It would say
Games Played: 9, Rushing Attempts: 1
I hope that makes sense. Basically I'd like to learn how to match keys in one JSON object with the key values in another.
Thank you very much for assistance.
You could nest your second AJAX call in the success function of your first call, then put your variable assignments and table creation into the second success function. Inside the second success function you'd use simple for loops to match each numerical statistic from the player data with the correct name of the statistic in the statistics data, like this:
$(document).ready(function () {
var statType = "seasonStats";
var season = "2018";
var week = "15";
var playersURL = "https://api.fantasy.nfl.com/v1/players/stats?format=json" + "&statType=" + statType + "&season=" + season + "&week=" + week;
var statURL = "https://api.fantasy.nfl.com/v1/game/stats?format=json";
// Now we get the stats
$.ajax({
url: statURL,
method: "GET",
success: function (response) {
const stats = response.stats;
// Then we get the players
$.ajax({
url: playersURL,
method: "GET",
success: function (response) {
const players = response.players;
// Now we do the rest of the logic
// Here's our table creation and header
var tbl = $("<table>");
$(tbl).addClass("table");
$(tbl).append("<thead><tr><th>ID</th><th>Team</th><th>POS</th><th>Player</th><th>Stat</th></tr></thead><tbody>");
// Here's where we create variables for each individual player
for (p = 0; p < 1; p++) {
let id = players[p].id;
let team = players[p].teamAbbr;
let pos = players[p].position;
let plyr = players[p].name;
// We create an empty object to hold the named statistics we're about to find
let statistics = {};
// Now we'll loop over the players and statistics to get names for all the stats
playerStats = players[p].stats;
for (playerStat in playerStats) {
for (s = 0; s < stats.length; s++) {
// if the player's statistic matches the id of the property from the stats object, we add that stat name and its total for that player as a property of the object we created above
if (playerStat === JSON.stringify(stats[s].id)) {
let statName = stats[s].name;
let statCount = playerStats[playerStat];
statistics[statName] = statCount;
}
}
};
// Now we turn our statistics object into text that can actually go into our table
let prettyStats = "";
for (statistic in statistics) {
prettyStats = prettyStats + `${statistic}: ${statistics[statistic]}
`
}
// Now that we have data for the player, we add a row to our table
$(tbl).append("<tr><td>" + id + "</td><td>" + team + "</td><td>" + pos + "</td><td>" + plyr + "</td><td>" + prettyStats + "</td>");
}
//Here's the bottom of our table and its creation inside the div
$(tbl).append("</tbody><br/><br/>");
$("#statOutput").append(tbl);
}
});
}
});
});
You'll probably want to do further text formatting on the output of prettyStats, but it gets you the data you're looking for.

Getting result 'undefined' in jquery

I'm trying to display some values using ajax for my asp.net application.
This is my C# code
[WebMethod]
public static string fillvazh(int id)
{
List<object> Users = new List<object>();
DataTable dt = new DataTable();
string query = "select Id,Name, PWD,Email,Mobile from Users where active='Y' and PM_Id='" + id + "' ";
dt = GetData(query); //Common function for getting data from db using DataAdapter
for (int i = 0; i < dt.Rows.Count; i++)
{
Users.Add(new
{
Id = dt.Rows[i]["Id"],
Name = dt.Rows[i]["Name"],
PWD = dt.Rows[i]["PWD"],
Email = dt.Rows[i]["Email"],
Mobile = dt.Rows[i]["Mobile"],
});
}
var json = (new JavaScriptSerializer().Serialize(Users));
return json;
}
My Jquery is:
<script type="text/javascript">
$(document).ready( function ( e ) {
$("[id*=pmid]").click(function () {
vl = $(this).data("val");
$.ajax({
type: "POST",
url: 'Default.aspx/fillvazh',
data: '{id:'+ vl +'}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
var data = result.d;
// var data = [{"Id":1,"Name":"Sam","PWD":iu875t,"Email":samjohn#domain.com,"mobile":"XXXXXXXX"},{"Id":2,"Name":"Titus","PWD":mghjgh76,"Email":titus#domain.com,"mobile":"XXXXXXXX"}]; //Working correctly.
var tr;
for (var i = 0; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].Id + "</td>");
tr.append("<td>" + data[i].Name + "</td>");
tr.append("<td>" + data[i].PWD+ "</td>");
$('#gvCustomers').append(tr);
}
},
failure: function (response) { },
error: function (response) { }
});
});
});
</script>
The output of console.log(data) is
[{"Id":1,"Name":"Sam","PWD":iu875t,"Email":samjohn#domain.com,"mobile":"XXXXXXXX"},{"Id":2,"Name":"Titus","PWD":mghjgh76,"Email":titus#domain.com,"mobile":"XXXXXXXX"}]
The output is undefined
But when I'm trying to hard code the console data, the output is getting normally, means if I use result.d value directly.
var data = [{"Id":1,"Name":"Sam","PWD":iu875t,"Email":samjohn#domain.com,"mobile":"XXXXXXXX"},{"Id":2,"Name":"Titus","PWD":mghjgh76,"Email":titus#domain.com,"mobile":"XXXXXXXX"}];
I'm not understanding why the output is still undifined and correct when hard code my json output.
Are you sure the output of console.log(data) is this ?
[{"Id":1,"Name":"Sam","PWD":iu875t,"Email":samjohn#domain.com,"mobile":"XXXXXXXX"},{"Id":2,"Name":"Titus","PWD":mghjgh76,"Email":titus#domain.com,"mobile":"XXXXXXXX"}]
if so, maybe the problem is properties PWD and Email
"PWD":mghjgh76,"Email":titus#domain.com
Right format should be:
"PWD":"mghjgh76","Email":"titus#domain.com"
Then, the solution is, in your C# code, when you add new object to Users, make sure those properties are string
PWD = dt.Rows[i]["PWD"].ToString(),
Email = dt.Rows[i]["Email"].ToString(),
As I see in your image you upload, result.d is currently in string format, so then you should use $.parseJSON
var users = $.parseJSON(result.d);
(PWD and Email should be string format like I talk above to make parseJSON work right)
Try following code.
var data = $.parseJSON(result);

Categorising SharePoint list items on a HTML using Javascript and JSON

I have a JavaScript page which is querying a SharePoint list. The information on the list regards IT hardware, Lap Tops, Tablets etc. The user inputs the specific type, and I have a drop down of more general hardware types.
This is what I've got:
and this is what I need:
So under the hardware headings the specifics get categorised. What's the best way to do this? JavaScript below:
function getDeviceDetails() {
var txtTitle = "";
var txtOverview = "";
var txtAccessories = "";
var txtDevicetype = "";
var txtTypicalDeviceUsage ="";
var txtKnownSystemIssues ="";
var txtLifeCycles = "";
var txtTrafficlight = "";
var imgDevicePicture = "";
var tempLCS2 = "";
var query = "http://collaboration-dev.norgine.com/sites/it/SystemInventory/_vti_bin/listdata.svc/Devices?$expand=Priority&$filter=Id eq " + window.DeviceId + "";
var call = $.ajax({
url: query,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
$.each(data.d.results, function(index, item) {
var tempID = item.Id;
var tempTitle = item.Title;
var DeviceOverView = item.Description;
var AccessDetails = item.Accessories;
var DeviceKind = item.DevicetypeValue;
var Usage = item.TypicalUsage;
var DevicePriority = item.PriorityValue;
var DeviceImage = item.DeviceImage;
txtTitle = "<p>"; //+ LifeCycleStart + "</p><p>" + LifeCycleStatus + "</p>";
txtOverview = "<p>" + DeviceOverView + "</p>";
txtAccessories = "<p>" + AccessDetails + "</p>";
txtDevicetype = "<p>" + DeviceKind + "</p>";
txtTypicalDeviceUsage = "<p>" + Usage + "</p>";
txtTrafficlight = "<p>" + DevicePriority + "</p>";
imgDevicePicture = "<img src='" + DeviceImage + "'>";
});
$('#devicedetails').append($(txtTitle));
$('#deviceoverview').append($(txtOverview));
$('#devicekind').append(txtDevicetype);
$('#deviceacc').append(txtAccessories);
$('#deviceuse').append(txtTypicalDeviceUsage);
$('#devicestatus').append(txtTrafficlight);
$('#imageContainer').append("<img src='/sites/IT/SiteAssets/"+txtTrafficlight.replace(/<[^>]*>/g, '')+".png' />");
$('.deviceimage').append(imgDevicePicture);
});
call.fail(function (jqXHR,textStatus,errorThrown){
alert("Error retrieving data: " + jqXHR.responseText);
});
}
You're taking records from a SharePoint list and displaying them grouped by a common column value. There are two ways to accomplish this.
Option 1: Perform Separate Queries
If you have three categories of devices (e.g. Laptop, Desktop, and Tablet) you can query the SharePoint list once for each category of items you wish to retrieve.
var urlEndpoint = "http://collaboration-dev.norgine.com/sites/it/SystemInventory/_vti_bin/listdata.svc/Devices$expand=Priority,Devicetype&$filter=Id eq " + window.DeviceId + " and ";
var laptopFilter = "DevicetypeValue eq 'Laptop'",
desktopFilter = "DevicetypeValue eq 'Desktop'",
tabletFilter = "DevicetypeValue eq 'Tablet'";
$.ajax({
url: urlEndpoint + laptopFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayLaptopResults);
$.ajax({
url: urlEndpoint + desktopFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayDesktopResults);
$.ajax({
url: urlEndpoint + tabletFilter,
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
}).done(displayTabletResults);
function displayLaptopResults(data){ /* your code here */ }
function displayDesktopResults(data){ /* your code here */ }
function displayTabletResults(data){ /* your code here */ }
This is only possible if you know the different categories beforehand and can compose your queries to filter against those categories. It has the advantage of working with smaller chunks of data at a time, and might be necessary when dealing with large lists.
If you don't know all the possible categories then consider the next option.
Option 2: Perform One Query and Post-process The Results
Alternatively, you can get all the results and place them into an in-memory data structure according to their category before displaying the records on the page.
Instead of having an array of items...
var results = [item1, item2, item3, item4, item5]
You'll have a hashmap with an array property for each category.
var results = {
category1: [item1, item4],
category2: [item2, item3],
category3: [item5]
}
The following code example demonstrates how you can process an array of items to categorize them, then render the results afterwards.
var data = {d:{results:[
{title:"X1 Carbon",DevicetypeValue:"laptop"},
{title:"T470",DevicetypeValue:"laptop"},
{title:"MS Surface Pro3",DevicetypeValue:"tablet"},
{title:"X270",DevicetypeValue:"laptop"},
{title:"M910",DevicetypeValue:"desktop"},
{title:"MS Surface Pro4",DevicetypeValue:"tablet"}]}};
var i = 0, len = data.d.results.length, item, category, devicesByCategory = {};
// loop through the results and add them to the devicesByCategory object
while(i < len){
item = data.d.results[i];
category = item.DevicetypeValue;
if(devicesByCategory[category]){
// if devicesByCategory already has an array for this item's category, add the item to it
devicesByCategory[category].push(item);
}else{
// otherwise, create a new array for the category
devicesByCategory[category] = [item];
}
i++;
}
// loop through all the categories and render them
for(var category in devicesByCategory){
var div = createCategorySection(category);
addResultsToSection(div,devicesByCategory[category]);
}
function createCategorySection(value){
var div = document.getElementById("output").appendChild(document.createElement("div"));
div.appendChild(document.createElement("h1")).appendChild(document.createTextNode(value));
return div;
}
function addResultsToSection(section,results){
var ul = section.appendChild(document.createElement("ul"));
i = 0; len = results.length;
while(i < len){
item = results[i];
ul.appendChild(document.createElement("li")).appendChild(document.createTextNode(item.title));
i++;
}
}
<div id="output"></div>

How to send table column values from a Javascript page to a C# page using Jquery

I have values that come from a dynamically created table from it's selected rows. inside each selected row i want all the td.innerText values that belong to be sent to a C# page, but i don't know how to. I was using JSON but I dont know if i used it properly.
function selectedRows()
{
var selectedItems = $('#ScannedLabelTable').find(':checkbox:checked').parents('tr');
var serial, kanbanNumber, customer, description, quantity;
$.each(selectedItems, function (i, item) {
var td = $(this).children('td');
for (var i = 0; i < td.length; ++i)
{
serial = td[1].innerText;
kanbanNumber = td[2].innerText;
customer = td[3].innerText;
description = td[4].innerText;
quantity = td[5].innerText;
}
console.log(serial + ' ' + kanbanNumber + ' ' + customer + ' ' + description + ' ' + quantity);
});
$.ajax({
url: SEND_TO_TEXTFILE_PAGE
, data: "labelSerial=" + serial + "&kanbanNumber=" + kanbanNumber + "&customer="
+ customer + "&description=" + description + "&quantity=" + quantity
, dataType: 'json'
, success: function (status) {
if (status.Error) {
alert(status.Error);
}
}
, error: Hesto.Ajax.ErrorHandler
});
}
EDIT: sorry I must have read this too quickly. This should do it. create an array and add the data object to it in the loop.
If you just create a json object using key value pairs you can send that object to your c# controller.
function selectedRows() {
var selectedItems = $('#ScannedLabelTable').find(':checkbox:checked').parents('tr');
var serial, kanbanNumber, customer, description, quantity;
var dataArray = new Array();
$.each(selectedItems, function (i, item) {
var td = $(this).children('td');
for (var i = 0; i < td.length; ++i)
{
var InfoObject = {
serial: td[1].innerText;
kanbanNumber: td[2].innerText;
customer: td[3].innerText;
description: td[4].innerText;
quantity: td[5].innerText;
};
dataArray.push(InfoObject);
}
});
$.ajax({
url: SEND_TO_TEXTFILE_PAGE
, data: dataArray
, dataType: 'json'
, success: function (status) {
if (status.Error) {
alert(status.Error);
}
}
, error: Hesto.Ajax.ErrorHandler
});
}

Categories