How to display API data using Ajax? - javascript

I want to be able to use the API from the code below to display data in a formatted way such as this example.
Job Title: Agricultural and Related Trades
Percentage of Occupancies in Area: 15.41%
You can find my poor attempt to display the data below. I am very new to Ajax, jQuery, JavaScript, etc.
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
$(function() {
$.ajax({
url: "http://api.lmiforall.org.uk/api/v1/census/jobs_breakdown?area=55.9895989531941,-3.796229726988194",
type: "get",
dataType: "json",
success: function(data) {
console.log(data[0].area);
outputString= data[0].description.percentage;
var paragraph = $("<p />", {
text: outputString
});
$("body").append(paragraph);
}
});
});
</script>

After successfully execute your GET request you will get your response at data variable now you can run a for loop to populate your expected outcome 'HTML' TEXT
than you can append it on your HTML body
I have used here JavaScript toFixed() Method keeping only two decimals
$(function() {
$.ajax({
url: "http://api.lmiforall.org.uk/api/v1/census/jobs_breakdown?area=55.9895989531941,-3.796229726988194",
method: "GET",
dataType: "json",
success: function(data) {
var str = "";
for(var i= 0; i < data.jobsBreakdown.length; i++){
str +='Job Title : '+data.jobsBreakdown[i].description+' and Related Trades <br> Percentage of Occupancies in Area : '+data.jobsBreakdown[i].percentage.toPrecision(2)+'% <br><br>';
}
$("body").html(str);
}
});
});
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>

Something like this is likely what you want:
<script>
$(function() {
$.ajax({
url: "http://api.lmiforall.org.uk/api/v1/census/jobs_breakdown?area=55.9895989531941,-3.796229726988194",
type: "get",
dataType: "json",
success: function(data) {
data.jobsBreakdown.forEach(function(job) {
var job_text = "Job Title: " + job.description;
var percentage_text = "Percentage of Occupancies in Area: " + job.percentage.toFixed(2) + "%"
$("body").append("<div style='margin-bottom: 10px;'><div>" + job_text + "</div><div>" + percentage_text + "</div></div>")
})
}
});
});
</script>

You can use string templates to create your paragraph content.
Use the <br /> HTML element to make a new line in the paraghraph.
let data = [{
area: 'Agricultural and Related Trades',
percentage: 15.41
}]
var paragraph = document.createElement('p');
paragraph.innerHTML = `Job Title: ${data[0].area}<br/>
Percentage of Occupancies in Area: ${data[0].percentage}%"`;
document.body.appendChild(paragraph);

You need to define a function to render a single item of description and percentage.
For parsing the percentage, you can use Number object
When you get the data back from Ajax, you need to loop on the items and pass each one of them to your render function you defined earlier (here I used forEach).
Generally, as rule of thumb, you have to split your code into functions each with single responsibility.
function renderItem(itemData) {
const title = $('<p/>').text('Job Title: ' + itemData.description);
const percentage = $('<p/>').text('Percentage of Occupancies in Area: '+ new Number(itemData.percentage).toFixed(2) + '%');
const item = $('<li/>').append(title, percentage);
$('#result').append(item);
}
$(function() {
$.ajax({
url: "http://api.lmiforall.org.uk/api/v1/census/jobs_breakdown?area=55.9895989531941,-3.796229726988194",
type: "get",
dataType: "json",
success: function(data) {
data.jobsBreakdown.forEach(renderItem);
}
});
});
Job Title: Agricultural and Related Trades
Percentage of Occupancies in Area: 15.41%
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="result"></ul>

Related

Use Ajax response script into a Django HttpResponse

I am trying to pass the ajax response obtained from view to the template using HttpResponse but I don't have any idea, how to do that?
view.py
analyzer=SentimentIntensityAnalyzer()
def index(request):
return render(request, "gui/index.html")
#csrf_exempt
def output(request):
sentences = request.POST.get('name',None)
senti = analyzer.polarity_scores(sentences)
context_dict = {'sentiment': senti}
return render(request,"gui/index.html", context = context_dict
I want the senti to be printed after the score on the page but I am unable to obtain it.
template file
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
<body>
<form action = Post>
Enter Sentence:<input id = "name" type = "text" name = "EnterSentence" encoding = "utf-8"><br>
<input onclick = "testfunction()" type = "button" value = "Submit" >
</form>
<div><strong>Score is {{ sentiment }}</strong></div>
</body>
<script>
var testfunction = () => {
var test = document.getElementById("name").value
console.log(test)
$.ajax({
type: "POST",
dataType: "json",
url: 'output/',
data:{
csrfmiddlewaretoken: '{{ csrf_token }}',
'name': test
},
success: function(response) {
console.log("Succesful return firm ajax call");
},
error: function(result){
console.log("Failure");
}
});
}
</script>
</html>
In your view.py return render(request,"gui/index.html", context = context_dict code is missing ending paranthesis.
This is the correct order of jQuery ajax:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
Your success and error fields are inside of data.
<script>
$(document).ready(function(){
$("button").click(function(){
$.ajax({url: "demo_test.txt", success: function(result){
$("#div1").html(result);
}});
});
});
</script>
</head>
<body>
<div id="div1"><h2>Let jQuery AJAX Change This Text</h2></div>
<button>Get External Content</button>
</body>
This is an example of how to use .html method of ajax jquery. You can adjust for your own.
Additionally, use below code to loop through response:
$.each( data, function( key, val ) {
HTMLString += <li id='" + key + "'>" + val + "</li>
});
and this should be inside of the function of success and then pass HTMLString into .html method
To make it clearer how to $.each works:
var numbers = [1, 2, 3, 4, 5, 6];
$.each(numbers , function (index, value){
console.log(index + ':' + value);
});

How to get my dynamically created div to show up on page after ajax call

I have a project that I am trying to implement with jquery. I have an add button, so everytime it is clicked, it will create a new record on in my database. I am trying to figure out how to get my ajax call to recognize the new data and display it on the screen, without me having to manually refresh the screen, I was hoping to just use fadeIn or something similar to only show my new div.
This is for a checklist system,so someone can edit a checklist by adding steps on the fly and reorder existing steps
I wrote a loadData function to loop through my records and append the appropriate data, but not sure how to auto refresh my div when someone adds a new step. I don't want to reload the entire page, only the newly created div.
$(function() {
loadData();
});
// drag and drop steps and update the database
$('#steps').sortable({
update: function(event, ui) {
var data = $(this).sortable('serialize');
data = data + '&id=' + json.IDchecklist + '&ver=' + json.Version;
$.ajax({
data: data,
type: 'POST',
url: '../Processes/Reorder.php',
success: (function() {})
});
}
});
//load data
function loadData() {
$.ajax({
url: '../json/test.php',
type: 'GET',
dataType: 'json',
success: function(data) {
json = data
$('#details').find('h2').html(data.IDchecklist);
$('#details').find('h4').html(data.Status);
$.each(data, function(k, v) {
if (k == "Steps") {
count = 1;
$.each(v, function(key, value) {
$('#steps').append('<span>' + count + '</span><div id=step' + value.IDstep + '>' + value.StepText + '</div>');
count++;
text[count] = value.StepText;
})
}
})
}
})
}
//add new step
$('#add').click(function() {
console.log(count);
div = $('#step-' + count);
$.ajax({
type: 'POST',
data: {
id: json.IDchecklist,
ver: json.Version,
step: count
},
url: '../processes/addStep.php',
success: (function() {
div.fadeIn('fast')
})
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<div class="jumbotron"></div>
<div id="details">
<h2></h2>
<h4></h4>
</div>
<div id="steps">
</div>
<button id=add value="Add">Add</button>

Alerting string using document.getElementById().innerHTML

I'm trying to alert a string, using document.getElementById().innerHTML, but it's alerting the code of the whole page, instead of the string inside the div. I need it to alert '121'. What am I doing wrong?
<script type = "text/javascript">
function getUrban(pageNum, stopAt, gotoUrl) {
var currentPage = "currentPage";
$.ajax({
type: "POST",
url: gotoUrl,
data: { pageNum : pageNum },
error: function(xhr,status,error){alert("error");},
success:function(data) {
document.getElementById("output").innerHTML = data;
currentPage = document.getElementById("output").innerHTML;
},
complete:function(data) {
alert(currentPage);
} //end of complete:function(data)
});
} //end of function getUrban(pageNum)
getUrban(121,422,"test.php");
</script>
<div id = "output"></div>
Output in Alert:
The full code of the whole page, plus some more code about setting the width.
Output in div with id 'output':
121
Need Alert:
121
test.php
$pageNum = $_POST['pageNum'];
echo $pageNum;
Since you're using jQuery to do the ajax why don't you use jquery for everything else also.
$('#output').text();
Will get only the text inside the div. Not the html elements as well.
It drives me crazy to see people using jQuery and have document.getElementById('id') in their code. You do realize that $('id') will get the same element but with jQuery wrapper so you can use jQuery functions on it. And it's so much shorter to type.
<script type = "text/javascript">
function getUrban(pageNum, stopAt, gotoUrl) {
$.ajax({
type: "POST",
url: gotoUrl,
data: { pageNum : pageNum },
error: function(xhr,status,error){alert("error");},
success:function(data) {
$("#output").html(data);
},
complete:function(data) {
alert($('#output').text());
} //end of complete:function(data)
});
} //end of function getUrban(pageNum)
getUrban(121,422,"test.php");
</script>
<div id = "output"></div>

Using document.currentScript to append data to divs

I want to append data into divs by passing their id as attributes in a script tag. In this example the first-div should get get 'test1' appended to it, and the second-div should get the 'test2' appended to it.
However, the result it that both 'test1' and 'test2' are appended to second-div. first-div is empty. I'm guessing it has to do with how document.currentScript is functioning. Is there any way to get the result I am looking for?
<div id="first-div"></div>
<div id="second-div"></div>
<script attr1="name1" attr2="name2" to-div="first-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test1");
});
</script>
<script attr1="name3" attr2="name4" to-div="second-div" type="text/javascript">
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
});
</script>
Also, in the solution, the scripts cannot have id attributes, which is why I am trying to use document.currentScript.
The reason for this is that the code will be hosted on my servers. The code will append information into the divs the user wants, given parameters passed through attributes on the script tag. In the end the user should be able to use:
<script attr1="var1" attr2="var2" to-div="custom-div" src="http://www.myurl.com/assets/script.js" type="text/javascript"></script>
To insert data into their custom-div based on code I run on my servers dependend on the parameters attr1 and attr2 they provide.
Your problem is that var append_div is a global variable and each time a new script tag is encountered it gets overwritten with the new value.
Since ajax is asynchronous , by the time the responses return the other script tags will have been evaluated so append_div will have the value of the last script tag.
You could fix this by creating a function that wraps the ajax
function doAjax(elementId, attr1) {
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}
doAjax(append_div, attr1);
An even better solution as pointed out by #Rhumborl is to use an IIFE
(function( elementId, attr1){
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function (data) {
$('#' + elementId).append("test2");
}
});
}(elementId, attr1);
Or wrap all of your code in an IIFE and no arguments would need to be passed in.
(function(){
var this_script = document.currentScript;
var attr1 = this_script.getAttribute('attr1');
var attr2 = this_script.getAttribute('attr2');
var append_div = this_script.getAttribute('to-div');
$.ajax({
url: "/dir?attr1=" + attr1,
type: 'GET',
success: function(data) {
$('#' + append_div).append("test2");
}
});
}();

Parsing json synchronously from url in javascript

I'm trying to get title of a youtube video. So i'm using jQuery to parse json. But it works asynchronously, so the answer comes after the page loaded. The result is:
http://www.youtube.com/watch?v=Ym0hZG-zNOk (undefined)
How can i fix it?
Thanks.
http://jsfiddle.net/3vQht/
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script>
var link = "http://www.youtube.com/watch?v=Ym0hZG-zNOk";
var videoID = link.substring(link.indexOf("=") + 1, link.length);
document.writeln("<a target='_blank' href='" + link + "'>" + link.bold() + "</a> (" + name(videoID) + ")<br>");
function name(value) {
var source = "http://gdata.youtube.com/feeds/api/videos/" + value + "?v=2&prettyprint=true&alt=jsonc&callback=?";
var fin;
$.getJSON(source, function(json) {
fin = json.data.title;
console.log(fin);
});
return fin;
}
</script>
</head>
<body>
</body>
</html>
Hy,
here is the solution :)
<script type="text/javascript">
function name(value) {
var source = "http://gdata.youtube.com/feeds/api/videos/" + value + "?v=2&prettyprint=true&alt=jsonc";
$.ajax({
type: 'GET',
url: source,
contentType: "application/json",
dataType: 'json',
success: function (json) {
alert("here is the title: "+json.data.title+" .Use it how you want!");
},
error: function (e) {
alert("error");
}
});
}
$(document).ready(function() {
var link = "http://www.youtube.com/watch?v=Ym0hZG-zNOk";
var videoID = link.substring(link.indexOf("=") + 1, link.length);
name(videoID);
});
</script>
If you want to get your data sync just use this version:
$.ajax({
type: 'GET',
url: source,
async: false,
contentType: "application/json",
dataType: 'json',
success: function (json) {
alert("here is the title: "+json.data.title+" .Use it how you want!");
},
error: function (e) {
alert("error");
}
});
}
getJSON is asynchronous, so when the return fin; is reached, the data hasn't been fetched yet.
Everything that depends on the JSON MUST be inside the success callback.
If you prefere, you can also fetch your data synchronously. Check the jQuery.ajax() documentation for the async parameter.
EDIT: Just figured that you're loading your data using JSONP and that it's not possible to do that synchronously. You need to use asynchronous callbacks instead.
I haven't played with their api, but a quick look at
https://developers.google.com/youtube/2.0/developers_guide_json
indicates that they support jsonp callbacks so that you can prepend a script that does sends the data to a callback function (just add &callback=yourFunction to the end of the url)
function prependScriptFromUrl(s){
var a=document.createElement("script");
var b=document.getElementsByTagName('head')[0];
a.src=s;
b.insertBefore(a,b.firstChild)
}

Categories

Resources