problems displaying my array via JSON object - json

Hi I am having a problems displaying my array via JSON object. I passed two variables to PHP which returns an array. I then wish to loop through the array and append the result to a div
The PHP works fine as I have tested this before adding the JQuery. When I use google chrome to inspect the console, I dump out data which displays as [] not an object, is this correct?
the contents of the array do not have a key, only a collection of list items with an image path for example
<li><img src="'.$image_path.'"</li>
I encode the array back to the listener,
echo json_encode($result);
code for JQuery
$.post('Look_Controller.php', {look: look, account: account}, function(data) {
$.each(data, function(i, item) {
$('#carousel-ul').empty();
content = item;
$(content).appendTo('#carousel-ul');
});
}, "json");
How do I append each individual result to the div (#carousel-ul)?,
I have also tried
content = item.this;
content = (this).item;
content = $(this).item;
I am not sure if it because the console.log(data) displays [] instead of object?
Hope someone can advise!
Thanks

What happen when you try this ?
$.post('Look_Controller.php', {look: look, account: account}, function(data) {
$('#carousel-ul').empty();
console.log(data);
$.each(data, function(i, item) {
console.log(item);
content = item;
// If "carousel-ul" is a <ul> tag uncomment the next line
// content = $('<li/>').html(content);
$(content).appendTo('#carousel-ul');
});
}, "json");

[] is an empty array. If that's what's being shown you have no data.
So it's probably not coming back from the server. Check the Network tab in the Chrome debugger and see what your response looks like.

Related

How to get clean json from wikipedia API

I want to get the result from a wikipedia page https://en.wikipedia.org/wiki/February_2 as JSON.
I tried using their API: https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&formatversion=2&format=json
Though it is giving it as Json format. The content is HTML. I want only the content.
I need a way to get clean result.
If you want plain text without markup, you have first to parse the JSON object and then extract the text from the HTML code:
function htmlToText(html) {
let tempDiv = document.createElement("div");
tempDiv.innerHTML = html;
return tempDiv.textContent || tempDiv.innerText || "";
}
const url = 'https://en.wikipedia.org/w/api.php?action=parse&page=February_19&prop=text&format=json&formatversion=2&origin=*';
$.getJSON(url, function(data) {
const html = data['parse']['text'];
const plainText = htmlToText(html);
const array = [...plainText.matchAll(/^\d{4} *–.*/gm)].map(x=>x[0]);
console.log(array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Update: I edited the code above according to the comment below. Now the function extracts all the list items putting them into an array.
I guess by clean you mean the source wikitext. In that case you can use the revisions module:
https://en.wikipedia.org/w/api.php?action=query&titles=February_2&prop=revisions&rvprop=content&formatversion=2&format=json
See API:Get the contents of a page and API:Revisions for more info.

Get a users youtube feed with knockout js?

Is this possible.. here's what I have atm, but my data object is just returning a load of jargon, what am I doing wrong? Am I doing anything.. right, for that matter?
I basically want to print out a list of a users videos (thumbnail and title, and make each one a clickable link to the video itself)
Thanks!
$(document).ready(function(){
$player.init();
})
var $player = (function(){
var player = {};
player.init = function(){
//init Youtube knockout
player.initYoutubeKnockout();
}
player.knockoutModel = {
videoData : ko.observableArray([]),
}
player.initYoutubeKnockout = function()
{
//load the Youtube json feed
$.ajax({
url: 'http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?v=2&alt=json',
type: 'GET',
dataType: 'jsonp',
data: {
count: 5
},
success: function(data, textStatus, xhr) {
player.doYoutubeKnockout(data.item);
}
});
}
player.doYoutubeKnockout = function( data )
{
player.knockoutModel.videoData(data);
ko.applyBindings(player.knockoutModel, $('#youtube-feed')[0]);
console.log($(this));
}
return player;
})();
Frankly you weren't doing much at all.
The JSON data you get back from YouTube is not from data.item, it's in a completely different structure.
I'm assuming you wish to get 5 uploads from the user. The parameter name would be max-results, not count.
Probably the only thing you did fine was set up the url but that's about it.
You need to examine how the JSON returned looks like. Check the API reference for the structure of an atom feed. This is in XML but the corresponding JSON responses will have pretty much the same format with some minor differences. Examine the object by writing it to the console to verify you're getting the right properties.
Once you understand that, you need to use the correct query to get what you're expecting. Check out their API reference on their query parameters.
To help simplify your knockout code, I would strongly recommend you take the response you get back and map it to an object with simplified property names. For instance, to get the thumbnails for an entry, you would have to access the media$group.media$thumbnail array. It would be easier if you can just access it through thumbnail.
Also, if your elements you are binding to need to bind multiple values, it would help to map the values in such a way that your bindings are made easier. For instance, when using the attr binding, you'd set up a property for each of the attributes you want to add. Instead you could just group all the properties in an object and bind to that.
I wrote up a fiddle applying all that I said above to do as you had asked for. This should help give you an idea of what you can do and how to do it.
Demo

Getting Current Data from KendoUI TreeView

I'm using a kendo UI tree with a remote data source from a JSON file.
I have a button on the tree page which gets the current data of the tree,sends it through a POST to a server and the server saves the current data to the JSON file so as the next time I reload the page,the changes I made will be kept.That's what I want to happen.
So I know the current data of the tree is in:
$("#treeview").data("kendoTreeView").dataSource.data()
Which means the data changes real time in there for example when someone drag and drops a node of the tree.
My problem starts when this data doesn't seem to change when I drag and drop nodes inside the tree,and only changes when I drag and drop a node on the root level of the tree and even then it doesn't do it correcly as the node should be moved in there as well but instead the node gets copied,leaving the past node in the tree as well...
For Example I have this tree:
If I make a drag and drop change like this:
And I send the data,save it and reload the change isn't made at all!
PS:Even when I view the current data after the change before sending it,I see that there is no change on the data at all even though I did a change visualy with a drag and drop.So it doesn't have to do with the sending,saving and the server.
On the other hand,if I make a change like this:
I can see in the current data that the moved node is added in the end of the data indeed but it is not deleted from it's initial position within the data!So if i send the current data to the server,save it and then refresh I get the result:
The code for viewing and sending the data is:
function sendData() {
var req = createRequest();
var putUrl = "rest/hello/treeData";
req.open("post", putUrl, true);
req.setRequestHeader("Content-type","application/json");
var dsdata = $("#treeview").data("kendoTreeView").dataSource.data();
alert(JSON.stringify(dsdata));
req.send(JSON.stringify(dsdata));
req.onreadystatechange = function() {
if (req.readyState != 4) {
return;
}
if (req.status != 200) {
alert("Error: " + req.status);
return;
}
alert("Sent Data Status: " + req.responseText);
}
}
Is this a Bug or am I doing something wrong?Has anyone been able to see the current data changing correctly on every drag and drop?
First and most important you have to use the latest version of KendoUI (Kendo UI Beta v2012.3.1024) still in beta but is where they have solved many problems.
Then, when you create the kendoTreeView you have to say something like:
tree = $("#treeview").kendoTreeView({
dataSource :kendo.observableHierarchy(data),
dragAndDrop:true
}).data("kendoTreeView");
Here the important is not using directly data array but wrapping it with kendo.observableHierarchy.
Then you will have the data updated with the result of drag & drops.
For me in addition to OnaBai answer I had to use the sync function on the save method. I am using Type Script.
this.treeData = new kendo.data.HierarchicalDataSource({
data: kendo.observableHierarchy([]),//Thanks OnaBai
schema: {
model: {
id: "MenuItemId",
children: "MenuItemChildren",
hasChildren: (e) => {
//this removes arrow next to items that do not have children.
return e.MenuItemChildren && e.MenuItemChildren.length > 0;
}
}
}
});
public save() {
this.treeData.sync().done(() => {
console.log("sync data");
var myType = this.treeData.view();
this.$http.post("/api/TreeViewPicker", myType)
.then((response) => {
});
});
}

JSON results into a variable and store in hidden input field

I wrote code below that is working perfectly for displaying the results of my sales tax calculation into a span tag. But, I am not understanding how to change the "total" value into a variable that I can work with.
<script type="text/javascript">
function doStateTax(){
var grandtotalX = $('#GRANDtotalprice').val();
var statetaxX = $('#ddl').val();
$.post('statetax.php',
{statetaxX:statetaxX, grandtotalX:grandtotalX},
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
// ...
});
return false;
};
</script>
Currently, $('.total-placeholder').html(data.total); is successfully placing the total number into here:
<span class="total-placeholder"></span>
but how would I make the (data.total) part become a variable? With help figuring this out, I can pass that variable into a hidden input field as a "value" and successfully give a proper total to Authorize.net
I tried this and id didn't work (see the testtotal part to see what I'm trying to accomplish)..
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
$testtotal = (data.total);
// ...
If you are using a hidden field inside a form, you could do:
//inside $.post -> success handler.
$('.total-placeholder').html(data.total);
$('input[name=yourHiddenFieldName]', yourForm).val(data.total);
This will now be submitted along with the usual submit. Or if you want to access the data elsewhere:
var dataValue = $('input[name=yourHiddenFieldName]', yourForm).val();
The "data" object you are calling can be used anywhere within the scope after you have a success call. Like this:
$.post('statetax.php',
{statetaxX:statetaxX, grandtotalX:grandtotalX},
function(data) {
data = $.parseJSON(data);
var total = data.total;
var tax = data.total * 0.19;
});
return false;
};
Whenever you get an object back always try to see with an alert() or console.log() what it is.
alert(data); // This would return <object> or <undefined> or <a_value> etc.
After that try to delve deeper (when not "undefined").
alert(data.total); // <a_value>?
If you want 'testotal' to be recognized outside the function scope, you need to define it outside the function, and then you can use it somewhere else:
var $testtotal;
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
$testtotal = (data.total);
EDIT:
The comments are becoming too long so i'll try and explain here:
variables defined in javascript cannot be accessed by PHP and vice versa, the only way PHP would know about your javascript variable is if you pass it that variable in an HTTP request (regular or ajax).
So if you want to pass the $testtotal variable to php you need to make an ajax request(or plain old HTTP request) and send the variable to the php script and then use $_GET/$_POST to retrieve it.
Hope that answers your question, if not then please edit your question so it'll be clearer.

stagger loading of ajax responses

I have a page that displays the status of all objects in a given set of database schemas. Schema objects are shown as a hierarchical tree (schema > object type > object name). There are a lot (thousands) of objects. The status is source-control related (is the object modified/deleted/added/unchanged in comparison to the source controlled version?).
I use a bit of ajax to load an icon representing the status of each object with the intention being that the status can be displayed whenever the asynchronous check completes. What actually happens, is that the loading icons freeze and after all statii requests have resolved, all icons display at the same time. This is unintended and gives the page load an undesirable and distinctly synchronous feel. I envisaged the loading icons changing individually to the correct status icon in some sort of staggered order.
How can I modify my javascript to give a better experience (icons transforming from loading gif to status png individually, rather than all at the same time)?
Here's some code:
$(window).load(function () {
#foreach (var schema in Model) {
foreach (var o in schema.Objects) {
#:$.getJSON('#Url.Action("ObjectStatus")', {service:'#schema.Service', schema:'#schema.Name', objectName:'#o.Name', objectType:'#o.Type'}, function (data) {
#:$('##string.Format("{0}-{1}", schema.Name, o.Name)').attr('src', '/Content/images/' + data + '.png');
#:});
}
}
});
...
<ul id="treeview">
#foreach (var schema in Model)
{
<li>#schema.Name<br />
<ul>
#foreach (var t in schema.Objects.Select(x=>x.Type).Distinct())
{
var objectType = t;
<li>#string.Format("{0}{1}", objectType, objectType.EndsWith("x") ? "es" : "s")<br />
<ul>
#foreach (var o in schema.Objects.Where(x => x.Type == objectType))
{
<li>
<img src="#Url.Content("~/Content/images/loading.gif")" alt="checking status..." id="#string.Format("{0}-{1}", schema.Name, o.Name)"/>
#Html.ActionLink(o.Name, "Diff", "Browse", new { service = schema.Service, schema = schema.Name, objectName = o.Name, objectType }, null)
</li>
}
</ul>
</li>
}
</ul>
</li>
}
</ul>
and here's what the finished tree looks like:
You're not going to get a true 'multi threaded' look and feel with javascript; it's simply not available.
What you can do is push all of your requests into an array, and then shift the first element off of the list for your next ajax request.
function getResponse()
{
if(myRequestArray.length == 0)
return;
var elementToRequest = myRequestArray.shift();
$.ajax({
url: '/some/url/',
data: { someData: elementToRequest.someData },
success: getResponse
});
}
Your callback will be the method invoked so you start the next request. This way, your UI can remain 'responsive' while the ajax requests complete. It's going to appear synchronous only so far as the ordering of the elements in the array get updated in order.
May not be best solution out there, but try this..
set
async : false
on your jquery call..