I'm a little stuck on how I can retrieve all data from a jsonp api when the data is split in pages. The callback looks like this:
{
entries: [],
page: 1,
pages: 101,
posts: 10054
}
the code under only gets me results from page 1, but I would like to get results from all 101 pages. If I add a query to the url like : &page=2 or &page=3 I can access objects from that page only, what I'm trying to is access all objects from all pages in one go....
would appreciate some help :)
$.getJSON('http://hotell.difi.no/api/jsonp/mattilsynet/smilefjes/tilsyn?callback=?', function(data){
var html = "";
$.each(data.entries, function(key,value){
html += '<p>' + value.navn + '</p>';
})
$('#test').html(html);
})
You can make first call to get the number of pages and in next calls you can loop through them.
Try below code
$.getJSON('http://hotell.difi.no/api/jsonp/mattilsynet/smilefjes/tilsyn?callback=?', function(data) {
var pages = data.pages;
for (var i = 1; i <= data.pages; i++) {
$.getJSON('http://hotell.difi.no/api/jsonp/mattilsynet/smilefjes/tilsyn?callback=?&page=' + i, function(data) {
$('#test').append("Page " + data.page + " Data >> ");
var html = "";
$.each(data.entries, function(key, value) {
html += '<p>' + value.navn + '</p>';
})
$('#test').append(html);
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
</div>
You can use jsonp using $.ajax() not by $.getJSON(). and you have to declare your callback method in your javascript code
$("#btn").click(function(){
$.ajax({
url: "http://hotell.difi.no/api/jsonp/mattilsynet/smilefjes/tilsyn?callback=myJsonpCallbackMethod",
dataType: "jsonp",
success: function( response ) {
//console.log( response ); // server response
}
});
});
function myJsonpCallbackMethod(data){
alert("Hello");
console.log( data ); // server response
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<button id="btn">Click Me</button>
Related
ok so i am creating a web app and i have run into some issues
first i make a request to an api endpoint this returns a json response i take what i need and ad it into a key value array
i then have to loop through all the items in this array and for each item i need to make a request to a second api endpoint that returns some html
i need to then append this html to an eliment on the page
i need this to be done one after another the issue i have is that the .each() loop finishes instantly while the requests are still on going in the background meaning the aliments are appended to the html eliment on the page way after they should
how can i make the loop wait untill the requests are done and html is appended before moving onto the next item in the array
$("#middlebox").fadeTo(3000, 0, function() {
$("#middlebox").html(LOADING);
});
$("#middlebox").fadeTo(3000, 1, function() {
var API_URL = window.location.href + 'api.php?action=channels&category='+$this.data("text")+'&username='+$("#username").val()+'&password='+$("#password").val();
var CHANNELS = {};
var API_CHANNELS = '<div class="Live">';
$.getJSON(API_URL).done( function( API_RESULT ) {
$.each( API_RESULT.items, function( API_INDEX, API_ITEM ) {
var API_ID = API_ITEM.stream_id;
var API_ICON = API_ITEM.stream_icon;
CHANNELS[API_ID] = API_ICON;
});
}).then( function() {
$.each( CHANNELS, function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
$.ajax({
url:EPG_URL,
type: 'GET',
dataType: 'html',
success:function(content,code) {
API_CHANNELS += content;
}
});
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
API_CHANNELS += '</div>';
$("#middlebox").html(API_CHANNELS);
$("#middlebox").fadeTo(3000, 1, function() {
});
});
});
});
Ajax calls are asynchronous so you can't use a synchronous loop to process the requests.
You can use Promise.all to wait for all ajax requests and then process replies in a loop.
Promise.all(CHANNELS.map(function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
return $.ajax({
URL: EPG_URL,
type: 'GET',
dataType: 'html'
}).then(function(content) {
return [CHANNEL_KEY, CHANNEL_VALUE, content];
});
})).then(function(channels) {
$.each(channels, function(CHANNEL_KEY, CHANNEL_VALUE, content) {
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
API_CHANNELS += content;
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
/* ... */
});
});
I've created a text field in a Django model. I want to highlight words when word is clicked. I've found this jsFiddle
How can I adjust it to send a GET request to Django when a word is selected to receive JSON from other website API? Thanks in advance!
$(function() {
editTxt('#myTxt');
editTxt('#myTxtDiv');
$('span').live('mouseover', function() {
$(this).addClass('hlight');
});
$('span').live('mouseout', function() {
$(this).removeClass('hlight');
});
});
function editTxt(selector) {
$(function() {
var newHtml = '';
var words = $(selector).html().split(' ');
for (i = 0; i < words.length; i++) {
newHtml += '<span>' + words[i] + '</span> ';
}
$(selector).html(newHtml);
});
}
You might do something like this by using $.ajax:
...
$("span").on("mouseover", function() {
xhr = $(this).addClass("hlight");
$.ajax({
method: "post",
url: "YOUR_DJANGO_API_URL",
data: { text: $(this).text() },
success: function(data) {
// replace HTML element or whatever.
console.log(data);
}
});
});
$("span").on("mouseout", function() {
xhr.abort();
$(this).removeClass("hlight");
});
...
Note you have to replace data object text attribute to whatever your API backend parameters accepts, and as mentioned in the comments you don't need .live()
Make sure to replace YOUR_DJANGO_API_URL with your backend API URL
THE CONTEXT
I'm developing a web app that loads contents dynamycally, retrieving data from a
catalogue of items stored as a MongoDB database in which records of the items and their authors are in two distinct collections of the same database.
Authors ID are stored in the item field creator and refer to the author field #id. Each item can have none,one or many authors.
Item sample
{
"_id" : ObjectId("59f5de430fa594333bb338a6"),
"#id" : "http://minerva.atcult.it/rdf/000000016009",
"creator" : "http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec",
"identifier" : "000000016009",
"issued" : "fine sec. XIV - inizi sec. XV",
"title" : "Quadrans vetus",
"label" : "Quadrans vetus"
}
Author sample
{
"_id" : ObjectId("59f5d8e80fa594333bb1d72c"),
"#id" : "http://minerva.atcult.it/rdf/0007e43e-107f-3d18-b4bc-89f8d430fe59",
"#type" : "foaf:Person",
"name" : "Risse, Wilhelm"
}
WHAT WORKS
I query the database submitting a string in a form, using this PHP script
ITEM PHP SCRIPT
<?php
require 'vendor/autoload.php';
$title=$_GET['item'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->items;
$regex=new MongoDB\BSON\Regex ('^'.$title,'im');
$documentlist=$collection->find(['title'=>$regex],['projection'=>['_id'=>0,'title'=>1,'creator'=>1,'issued'=>1]]);
$items=$documentlist->toArray();
echo (json_encode($items));
?>
called by a Javascript script (new_search.js) using ajax, that has also the responsibility to attach to html document a <li class=item> for every item that matches the query, inserting the JSON fields and putting them in the provided tags ( <li class=item-name>,<li class=auth-name, and the last <li> in div class=item-info for date).
WHAT DOES NOT WORK
My intent is reproduce the pattern to retrieve author names from another collection in the same database, querying it using author field #id from the html tag <li class=auth-name, using a similar php script and a similar ajax call.
I tried to make a nested ajax call (in the one I used to retrieve the items infos) to invoke author_query.php that performs the MongoDB query on the collection of authors.
So, the question is: Is it possible use the $_GET superglobal to get the html tag that contains the author id #id in order to search it in the database?
Otherwise, how can I adjust the code to pass a javascript variable to php (not by user input) that lets me keep the content already loaded on the page?
UPDATES
To make clearer the question, I follow the tips in the comments and I updated my scripts using JSON directly to provide the needed data.
I also perfom a debug on the js code and it's clear that PHP don't provide any response,in fact ajax calls for authors name fails systematically.
I suppose that occurs because PHP don't receive the data dueto the fact I'm not using the correct syntax probably (in js code or in the php with $_GET or in both) to pass the variable author (I also tried data:'author='+author treating the JSON object author has a string). Anyway I don't understand what is the correct form to write the variable to pass using the data field of ajax().
MY SCRIPTS
JS SCRIPT new_search.js
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
var author;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
async:false,
success: function (items) {
for (var i = 0; i < items.length; i++) {
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
$('.item').each(function () {
author = $(this).find('.auth-name').text();
if (author == 'undefined')
$(this).find('.auth-name').text('Unknown');
else if(author.indexOf(',')!=-1) {
author='[{"author":"'+author+'"}]';
author=author.replace(/,/g,'"},{"author":"');
author = JSON.parse(author);
console.log(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text('');
var author_text=' ';
for(var i=0;i<auth_json.length;i++)
author_text+=auth_json.name+' ';
$(this).find('.auth-name').text(author_text);
},
error: function () {
console.log('Error 1');
}
});
}
else{
author='{"author":"'+author+"}";
author=JSON.parse(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text(auth_json.name);
},
error: function () {
console.log('Error 2');
}
});
}
});
});
});
AUTHOR PHP SCRIPT author_query.php
<?php
require 'vendor/autoload.php';
$auth=$_GET['author'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
if(is_array($auth)){
foreach ($auth as $a){
$document=$collection->findOne(['#id'=>$a],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo (json_encode($auth_json));
?>
"I'm sure that authors array... is not empty and actually contains the authors IDs". You mean the jQuery object $('.item')? I think that it is empty, because it is created too soon.
The first $.ajax call sends an ajax request and sets a handler to add more stuff to the HTML, including elements that will match the CSS selector .item. But the handler doesn't run yet because it's asynchronous. Immediately after this, the object $('.item') is created, but it's empty because the new .item elements haven't been created yet. So no more ajax requests are sent. Some time later, the call to item_query.php returns, and the new HTML stuff is added, including the .item elements. But by now it's too late.
You say the array was not empty. I suspect you checked this by running the CSS selector after doing the search, after the return of the ajax call.
A lot of newbies have problems like this with asynchronous javascript. If you want to use the result of an asynchronous function in another function, you have to call the second function inside the callback function of the first one. (Actually there are more sophisticated ways of combining asynchronous functions together, but this is good enough for now.)
On a side note, you've done this in a slightly strange way where you save data in HTML, and then read the HTML to do some more stuff. I wouldn't use HTML as a storage place - just use variables like you would for most other things.
Try this:
$.ajax({
url: "item_query.php",
...
success: function (items) {
for (var i = 0; i < items.length; i++) {
var author = items[i].creator;
var authors;
// insert code here to generate authors from author.split(',') .
// authors should look something like this: [{author: 'http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec'}] .
$.ajax({
url: "author_query.php",
type: "GET",
data: JSON.stringify(authors),
...
success: function (auth_json) {
...
},
error: function () {
console.log('Error 1');
}
});
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
I make the first call to retrieve the item infos asynchronous and the nested that search for the authors name synchronous. In this way I solved the problem.
For sure it is not the best solution, and it needs a quite long,but acceptable, time (<1 second) to load the content.
JS SCRIPT
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
success: function (items) {
for (var i = 0; i < items.length; i++) {
var authors_names=' ';
var authors= JSON.stringify(items[i]);
if(authors.indexOf('creator')!=-1){
if(authors.charAt(authors.indexOf('"creator":')+'"creator":'.length)!='[')
authors=authors.substring(authors.indexOf('"creator":"'),authors.indexOf('"',authors.indexOf('"creator":"')+'"creator":"'.length)+1);
else
authors=authors.substring(authors.indexOf('"creator"'),authors.indexOf(']',authors.indexOf('"creator"'))+1);
authors='{'+authors+'}';
//console.log(authors);
$.ajax({
url: "author_query_v3.php",
type: "GET",
data: 'authors='+authors,
dataType:"json",
async:false,
success: function (auth_json) {
authors=[];
authors=auth_json;
var author;
for(var j=0;j<authors.length;j++){
author=JSON.parse(authors[j]);
authors_names+=author.name+" | ";
}
console.log(authors_names);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR+' '+textStatus+ ' '+errorThrown);
}
});
}
else{
authors_names='Unknown';
}
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + authors_names+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
});
});
PHP SCRIPT
<?php
require 'vendor/autoload.php';
$auth=$_GET['authors'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
$auth=json_decode($auth);
$auth=$auth->creator;
if(is_array($auth)) {
foreach ($auth as $a) {
$document = $collection->findOne(['#id' => $a], ['projection' => ['_id' => 0, 'name' => 1]]);
$auth_json[] = (MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo(json_encode($auth_json));
?>
I am using PHPstorm IDE and i'm trying to render the following JSON and it gets stuck showing only the <ul></ul> without spitting the <li>'s into HTML the each function. Any idea what could be the issue?
thanks.
Script.js:
$(function(){
$('#clickme').click(function (){
//fetch json file
$.ajax({
url:'data.json',
dataType: 'json',
success: function(data){
var items = [];
$.each(data, function (key, val) {
items.push('<li id=" ' + key + '">' + val + '</li>');
});
$('<ul/>', {
'class': 'tasks',
html: items.join('')
}).appendTo('body');
},
statusCode: {
404: function(){
alert('there was a problem with the server. try again in a few secs');
}
}
});
});
});
And the JSON:
{"id":"1","mesi":"mesima 0","done_bool":"1"},{"id":"2","mesi":"mesima 1","done_bool":"0"},{"id":"3","mesi":"mesima 2 ","done_bool":"1"},{"id":"4","mesi":"mesima 3","done_bool":"1"}
My HTML is just an a href that spits out the click ID:
Get JSON
<script>
$(document).ready(function(){
$("button").click(function(){
$.getJSON("demo_ajax_json.js", function(result){
$.each(result, function(i, field){
$("div").append(field + " ");
});
});
});
});
</script>
<button>Get JSON data</button>
By Using this Method You can Easily get Your JSON value In HTML
Try this one :)
$.ajax({
url: 'data.json',
dataType: 'json',
success: function(data){
var html = "<ul>";
items = data.map(function(obj){
html += "<li id='" + obj.id + "'>" + obj.mesi + "</li";
});
html += "</ul>";
$('body').append(html);
I would try with some like this
$(function(){
$('#clickme').click(function (){
//fetch json file
$.ajax({
url:'data.json',
dataType: 'json',
success: function(data){
// uncomment line below if data is a single JSON
// data = [data]
var items = [];
// we create a list where we will append the items
var list = document.createElement("ul");
data.forEach(function(item){
// we create a list item
var listItem = document.createElement("li");
// we set the attributes
listItem.setAttribute("id", item.id ); // item.id or the property that you need
// we add text to the item
listItem.textContent = item.mesi;
// We append the list item to the list
list.appendChild(listItem);
});
// we append the list to the body
$("body").html(list);
},
statusCode: {
404: function(){
alert('there was a problem with the server. try again in a few secs');
}
}
});
});
});
Try like this:
success: function(data){
var items = '';
$.each(data, function (key, val) {
items += '<li id=" ' + key + '">' + val + '</li>';
});
ul = $('<ul/>').html(items);
$('body').append(ul);
}
for multiple objects
success: function(datas){
var items = '';
$.each(datas, function (i,data) {
$.each(data, function (key, val) {
items += '<li id=" ' + key + '">' + val + '</li>';
});
});
ul = $('<ul/>').html(items);
$('body').append(ul);
}
output
<ul>
<li id=" id">1</li>
<li id=" mesi">mesima 0</li>
<li id=" done_bool">1</li>
<li id=" id">2</li>
<li id=" mesi">mesima 1</li>
.
.
</ul>
Try like this:
$(function() {
$('#clickme').click(function() {
// fetch json file
$.ajax({
url : 'data.json',
dataType : 'json',
// please confirm request type is GET/POST
type : 'GET',
success : function(data) {
// please check logs in browser console
console.log(data);
var ulHtml = "<ul>";
$.each(data, function(key, obj) {
ulHtml += '<li id="' + obj.id + '">' + obj.mesi + '</li>';
});
ulHtml += "</ul>";
// please check logs in browser console
console.log(ulHtml);
$('body').append(ulHtml);
},
error : function(jqXhr, textStatus, errorThrown) {
console.log(errorThrown);
alert(textStatus);
}
});
});
});
<button id="clickme">Get JSON data</button>
I log json data and created ul html, Please check logs in browser console
I'm not sure how you want to output each item, so I made a simple suggestion, you can easily change the HTML to what you need. Here is working code:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<body>
Get JSON
<script>
$(function() {
$('#clickme').click(function() {
//fetch json file
$.ajax({
url: 'data.json',
dataType: 'json',
success: function(data) {
var items = [];
$.each(data, function(key, val) {
// the HTML output for each item
var done = (val.done_bool === '1') ? 'true' : 'false';
items.push('<li id=" ' + val.id + '">' + val.mesi + ': ' + done + '</li>');
});
$('<ul/>', {
'class': 'tasks',
html: items.join('')
}).appendTo('body');
},
statusCode: {
404: function() {
alert('there was a problem with the server. try again in a few secs');
}
}
});
});
});
</script>
</body>
</html>
data.json
[{"id":"1","mesi":"mesima 0","done_bool":"1"},{"id":"2","mesi":"mesima 1","done_bool":"0"},{"id":"3","mesi":"mesima 2 ","done_bool":"1"},{"id":"4","mesi":"mesima 3","done_bool":"1"}]
I also created a __jsfiddle__ so you can test it directly. (The AJAX call is simulated with the Mockjax library): https://jsfiddle.net/dh60nn5g/
Good to know:
If you are trying to load the JSON from another domain, you may need to configure CORS (Cross-origin resource sharing):
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Isn't this supposed to be a GET request? i think you are missing the method on your Ajax request. You should add
method: 'GET'
to your ajax request. I think this is a big deal in making ajax request.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
Am getting data from ajax call and appending the data to table. Am getting title and url from the data. Now when i click on the url data of table , i need to call a outer javascript function with the clicked url data.
<script>
jquery(document).ready(function(){
jquery(#button).click(function{
showData();
});
});
function showData(){
var total = "";
var final = "";
jquery.ajax({
url : "AJAX_POST_URL",
type: "POST",
data : input,
dataType: "json",
success: function(jsondata)
{
//data - response from server
var document= jsondata.data.results; //am getting array of objects
for(int i=0; i<document.length; i++){
var tr = "<tr>";
var td = "<td>" + "Title : " +
document[i].title + "Url :" + "<a href=''>" + document[i].url + </a> + "</td></tr>";
final = tr + td;
total= total + final ;
}
$("#docTable").append(total) ;
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("error");
}
});
}
</script>
<script>
function download(){
//inside this function i need to get the value of document[i].url
}
</script>
You really should structure your program quite a bit better, and it would be easier if you could put your complete example up on jsfiddle.net.
But a quick solution in your current code may be to make "document" a global variable. Beware that document already is a global variable in the BOM (Browser Object Model), so use something else like say "docs".
<script>
// Global variable
var docs;
jquery(document).ready(function(){
jquery(#button).click(function{
showData();
});
});
function showData(){
var total = "";
var final = "";
jquery.ajax({
url : "AJAX_POST_URL",
type: "POST",
data : input,
dataType: "json",
success: function(jsondata)
{
//data - response from server
docs = jsondata.data.results; //am getting array of objects
for(int i=0; i<document.length; i++) {
var tr = "<tr>";
var td = "<td>" + "Title : " +
docs[i].title + "Url :" + "<a href=''>" + docs[i].url + </a> + "</td></tr>";
final = tr + td;
total = total + final;
}
$("#docTable").append(total) ;
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("error");
}
});
}
</script>
<script>
function download(){
//inside this function i need to get the value of document[i].url
// You have access to docs through the global variable
for(var i=0;i < docs.length;i++) {
console.log(docs[i].url)
}
}
</script>