Create nested menu via 3 json files - javascript

I am trying to make a nested menu from 3 json files, but In the first step I stuck, it return nothing:
var json = {};
$.getJSON("/api/category.json", function(data){
json.category = data;
});
$.getJSON("/api/subcat.json", function(data){
json.subcat = data;
});
$.getJSON("/api/subsubcat.json", function(data){
json.subsubcat = data;
});
$.each(json, function(i,v) {
console.log(json[i]); // it return nothing
});
But when I tried console.log(json) it return object, but even when I get console.log(json.category) It return nothing, no error in console log.
If I solve this issue I want to make a nested menu with this three json file in a loop, something like this:
var obj = '';
$.each(json.category, function(i, v) {
obj += '<li data-id="' + data[i]['id'] + '">' + data[i]['name'] + '<ul>';
$.each(json.subcat, function(i, v) {
if (json.subcat["cat_id"] == json.category["id"]) {
obj += '<li data-id="' + data[i]['id'] + '">' + data[i]['name'] + '</li>';
}
});
obj += '</ul>';
// also subsub cat
$('.simulate-cat').append($(obj));
});
<ul class="simulate-cat"></ul>
Is this way right to make nested menu?
Thanks in advance

Problem is that you're not waiting for the requests to complete. Because of that json properties aren't populated yet
It should look like this
$.when($.getJSON("/api/category.json"), $.getJSON("/api/subcat.json") , $.getJSON("/api/subsubcat.json")).done(function( a1, a2, a3 ) {
json.category = a1[0];
json.subcat = a2[0];
json.subsubcat = a3[0];
// create menu here
});
See $.when for more info about how to wait for multiple async callbacks

Related

How to correctly populate a drop down list via ajax and MVC controller

I've searched quite a bit for this answer and can't find much that covers what I need.
I have some data stored in a db table I want to populate certain drop down lists with. On the document.ready I have an AJAX call to the controller requesting the data based on a parameter I send it. The controller returns the data as Json. I'm new to the process of Json so, figuring out what to with it once it returns is where I'm stuck.
I'm able display the data returned from the controller in an alert or console.log when it returns, so I know the right values are there, but I can't figure out how to populate the dropdown list with those values. All the data is, is about 5 to 10 ints. (not returned as ints, I know, but they're things like 65, 70, 2, 10, 11) I've tried some various options and nothing seems to work.
I can static the values in an array and that actually will populate the drop down list. I've tried populating that same array with the returned data, but no success that way. Here is the ajax call:
//Fill symbols drop down list
function returnSymbols(cc) {
var sendData = JSON.stringify({ 'ul': cc });
$.ajax({
url: '/Trucking/returnSymbols',
type: 'POST',
contentType: 'application/json',
data: sendData,
success: function (data) {
//alert('success');
console.log('success, yes');
alert(data);
var numbers = [];
var obj = jQuery.parseJSON(data);
/* If I do this and static these, it does work
var numbers = [1, 2, 3, 4, 5] */
var option = '';
for (var i = 0; i < numbers.length; i++) {
option += '<option value="' + numbers[i] + '">' + numbers[i] + '</option>';
}
$('#ddlMcalSymbols').append(option); //fill ddl with these values.
},
error: function () {
//alert('Error');
console.log('Error');
}
});
}
To reiterate I have tried things like numbers.push(obj) or even. .push(data), but those aren't working.
Since the controller returns a Json value I was under the impression I needed to parse that Json in order to do anything with it. Here is the controller if it helps at all:
[HttpPost]
public ActionResult returnSymbols(string ul)
{
List<Get_CIF_SymbolsVM> symbols;
Guid newGuid = Guid.Parse(ul); //parse param as Guid
using (TruckingDb db = new TruckingDb())
{
symbols = db.GetSymbols.ToArray().OrderBy(x => x.RID).Select(x => new Get_CIF_SymbolsVM(x)).ToList();
}
var syms = (from s in symbols
where s.UniqLineType == newGuid
select s.SymbolCode).Distinct();
return Json(syms, JsonRequestBehavior.AllowGet);
}
Any help would be greatly appreciated.
EDIT: Updating the process to explain a bit more.
Had some success, but it's still not correct.
Here is the ajax call. I changed just a few items. It brings back the correct data, but it displays all array items as one line. I need each value in the array as a single value in the drop down list.
var sendData = JSON.stringify({ 'ul': cc });
$.ajax({
url: '/Trucking/returnSymbols',
type: 'POST',
contentType: 'application/json',
data: sendData,
success: function (data) {
//alert('success');
console.log('success, yes');
alert(data);
var numbers = [];
numbers.push(data);
var option = '';
//Added two for loops to show what I've tried.
for (var i = 0; i < numbers.length; i++) {
option += '<option value="' + numbers[i] + '">' + numbers[i] + '</option><br>';
}
$('#ddlMcalSymbols').append(option);
//Tried this option to fill ddl
for (var i = 0; i < numbers.length; i++) {
option = '<option value="' + numbers[i] + '">' + numbers[i] + '</option><br>';
$('#ddlMcalSymbols').append(option);
}
//This Jquery foreach only returns one value to the ddl
$.each(numbers, function (i, value) {
console.log(value);
option += '<option value="' + value[i] + '">' + value[i] + '</option>';
});
$('#ddlMcalSymbols').append(option);
},
error: function () {
//alert('Error');
console.log('Error');
}
});
It brings back the data, but in the drop down both of the for loops above fill the ddl as one long looking string. "61,62,64,66,70,71,72" .. They don't show up as single select values.
I tried parts of the code, and it seems you are overlooking that the var numbers never acquires values.
I also usually prefer to create jquery objects rather than manually compile html; it is easier to develop this way. The code fails with more detail.
Something on the lines of:
var listEl=$('#ddlMcalSymbols');
for (var key in obj) {
jQuery('<option value="' + obj[key] + '">' + obj[key] + '</option>').appendTo(listEl);
}
but in better order
Worked out a solution that while it functions, there is some odd behavior with the CSS of it. I'm using a multiselect drop down called bootstrap-select. Has a .js and .css file. I needed to fill the multiselect drop down with values from a db instead of hard-coding them in with the method.
I use a post ajax call to send a parameter to the controller which retrieves the values I need based on it. I don't know if it's the bootstrap-select or a limitation with multiselect, but it did not like displaying the Json data. My ajax call is already parsing the Json, so that wasn't it. After multiple attempts and trials I figured out the only thing that really works is with an int array. When I had the string array it would display everything as either one long string or only one value. Additionally, even now with it working as I would like, I have to reload the page every time I make a change to the .js file i'm working on. That screws up the bootstrap-select.css file. NO IDEA AS TO WHY. What happens is every 3 to 4 page reloads the values are outside the drop down list and smooshed together like a bunch of unreadable text. (See pic above) I press ctrl + shft + R to clear the chromes cached css and it goes back to how it should look and function. Long-winded, but true. Here is my ajax call with some comments, so you can see what I did. I'm sure there may be more elegant and straightforward ways of doing this, but it was an improvement on what I already had. Maybe it will help someone else.
function returnSymbols(cc) {
var sendData = JSON.stringify({ 'ul': cc });
$.ajax({
url: '/Trucking/returnSymbols',
type: 'POST',
contentType: 'application/json',
data: sendData,
success: function (data) {
var num = [];
var num1 = [];
//Push all returned values into num array
$.each(data, function (index, value) {
num.push(value);
});
console.log(num); // console out to ensure values have been pushed
//convert the string array into an int array
for (var i in num) {
num1[i] = parseInt(num[i]);
}
console.log(num1); //conosle out to ensure values have parsed correctly
fillddl(num1); // send int array to fill drop down func
},
error: function () {
//alert('Error');
console.log('Error');
}
});
}
Then the Function to actually send the values to the drop down list. Very similar to what I've found in other methods.
function fillddl(sym)
{
var s = '';
for (var i = 0; i < sym.length; i++)
{
s += '<option value="' + sym[i] + '">' + sym[i] + '</option>';
}
$(".ddlMcalSymbols").html(s);
}
you can do something like this
In action method
[HttpPost]
public ActionResult getCicitesAction(int provinceId)
{
var cities = db.cities.Where(a => a.provinceId == provinceId).Select(a => "<option value='" + a.cityId + "'>" + a.cityName + "'</option>'";
return Content(String.Join("", cities));
}
The ajax call would be like this:
$("province_dll").change(function(){
$.ajax({
url: 'getCitiesController/getCitiesAction',
type: 'post',
data: {
provinceId: provinceIdVar
}
}).done(function(response){
$("cities_dll").html(response);
});

Getting data from API with AJAX

I am trying to get data from API and display them using AJAX
I have this code
$(document).ready(function(){
$('.show').click(function(){
$.ajax({
url: 'url',
dataType: 'json',
success: function(data) {
var items = [];
$.each(data, function(key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'interest-list',
html: items.join('')
}).appendTo('body');
},
statusCode: {
404: function() {
alert('There was a problem with the server. Try again soon!');
}
}
});
});
});
I have this result:
[object Object],[object Object],[object Object],[object Object],
What must I fix in my code?
$.each iterates over the array, and key was the index of the array, and val was the entire object
You could change this line of code
items.push('<li id="' + key + '">' + val + '</li>');
to
var key = Object.keys(val)[0];
items.push('<li id="' + key + '">' + val[key] + "</li>");
to just get the first key directly.
Here is the documentation for
Object.keys.
First of all, you'd better add the type:'GET' field to define what kind of call are you doing.
Then you can use var json = JSON.parse(data) to read all the incoming data from data like this:
var time = json['foo'];
or if you have an array:
var time = json[index]['foo'];
you can find more details here https://www.w3schools.com/js/js_json_parse.asp and here https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

Client call JSON result show as undefined

I have a set of json data which is generated in php with json_decode function, here is the results:
I then create a html document and try to call the result using jquery $.getJSON:
var apiSrc = 'http://localhost/api/ws-data';
var showData = $('#result');
$(function(){
$.getJSON(apiSrc, function(data) {
console.log(data);
var items = data.blog.map(function (item) {
return item.key + ': ' + item.value;
});
showData.empty();
if(items.length) {
var content = '<li>' + items.join('</li><li>') + '</li>';
var list = $('<ul />').html(content);
showData.append(list);
}
});
showData.text('Loading...');
});
and the results for above is:
REST - Get JSON from PHP file on the server side
undefined: undefined
undefined: undefined
undefined: undefined
undefined: undefined
..
Its shown the key and value as undefined: undefined
What's goes wrong in the script?
I think you should access the correct properties such as pid,category etc of response,
var items = data.blog.map(function (item) {
return item.pid + ': ' + item.category;
});

put $.getJSON(url, function(data) in a loop but yield wrong result

I run several calls to the Instagram API by using a loop but it yields weird result that I couldn't understand.
for(var i = 0; i < tags.length; i++){
document.write('search: ' + i + 'round');
document.write(tags[i] + ' ');
document.write('<hr />');
var url = 'https://api.instagram.com/v1/tags/'+ tags[i] +'/media/recent?&client_id=5a7b13571ced47418dd539e6fc97a67f&count='+count+'&callback=?';
$.getJSON(url, function(data) {
console.log(data.data.length);
if(data.data.length === 0){
//$('ul.images').append('<li>No results</li>');
} else {
$.each(data.data, function(index, value){
//console.log(value);
var imgUrl = value.images.low_resolution.url,
imgUser = value.user.username,
imgLink = value.link;
it.push(imgLink);
document.write(value.link + '<br />');
//$('ul.images').append('<li><img src="'+imgUrl+'"/></li>');
});
}
document.write('---------------------' + '<br />');
});
}
When I search three tags, cat, dog, pig, the result is:
search: 0roundcat
search: 1rounddog
search: 2roundpig
5 instagram image links
---------------------
5 instagram image links
---------------------
5 instagram image links
---------------------
So it seems the it first loop the three document.write() statement and then getting into $.getJSON() statement.
Any thoughts?
If your question is why the "i + round + tag" output comes before the output with the links, that is because getJSON() is asynchronous, i.e. it starts a request and returns immediately.
Then, after the for loop is finished, the execution has returned to the event loop and the results of the asynchronous requests have arrived, they are printed in the order that they arrived.
There are several ways to get around this, one would be something like this:
var tags = ['cat','dog','pig'];
function start_next_request() {
var tag = tags.shift();
var url = ...
$.getJSON(url, function (data) {
...
start_next_request();
}
}
start_next_request();

jquery control execution of the callback functions

Function socialbookmarksTableData(data) is called by another function to generate the content of a table -- data is a JSON object. Inside the function i call 2 other functions that use getJSON and POST (with json as a return object) to get some data. The problem is: though the functions execute correctly i get undefined value for the 2 variables (bookmarkingSites, bookmarkCategories). Help with a solution please.
function socialbookmarksGetBookmarkCategories(bookmarkID)
{
var toReturn = '';
$.post("php/socialbookmark-get-bookmark-categories.php",{
bookmarkID: bookmarkID
},function(data){
$.each(data,function(i,categID){
toReturn += '<option value ="' + data[i].categID + '">' + data[i].categName + '</option>';
})
return toReturn;
},"JSON");
}
function socialbookmarksGetBookmarkSites()
{
var bookmarkingSites = '';
$.getJSON("php/socialbookmark-get-bookmarking-sites.php",function(bookmarks){
for(var i = 0; i < bookmarks.length; i++){
//alert( bookmarks[i].id);
bookmarkingSites += '<option value = "' + bookmarks[i].id + '">' + bookmarks[i].title + '</option>';
}
return bookmarkingSites;
});
}
function socialbookmarksTableData(data)
{
var toAppend = '';
var bookmarkingSites = socialbookmarksGetBookmarkSites();
$.each(data.results, function(i, id){
var bookmarkCategories = socialbookmarksGetBookmarkCategories(data.results[i].bookmarkID);
//rest of the code is not important
});
$("#searchTable tbody").append(toAppend);
}
You return the variables from the callback functions, not the functions that you actually call. After the callback functions are called control is returned to the functions which have no return statements, so they 'return' undefined by default. You need to return values from socialbookmarksGetBookmarkCategories and socialbookmarksGetBookmarkSites not just from callback functions within them.
You need to execute the code in your socialbookmarksTableData function as a response to the $.getJSON call. The problem is that you are returning right away, but the JSON callback hasn't yet fired.

Categories

Resources