Clean up Django Ajax JSON GET Request - ajax

So I'm trying to use AJAX to load some data. I can get the data to load but it's stuck in json. How do I make it so it's cleaner & more human readable?
//jquery
$.get("/get_artwork", function(data) {
var obj = jQuery.parseJSON(data)
$('.result').append("<br/> " + data + " ");
});
#Views.py
def get_artwork(request):
if request.is_ajax():
artwork = Artwork.objects.all()[1:]
if request.method == 'GET':
data = serializers.serialize("json", artwork, fields=('name','updated'), indent=2, use_natural_keys=True)
return HttpResponse(data,mimetype='application/javascript')
elif request.method == 'POST':
message = "This is an XHR POST request"
# Here we can access the POST data
print request.POST
else:
message = "Hello"
return HttpResponse(message)
and this is what renders:
[ { "pk": 3, "model": "artworks.artwork", "fields": { "updated": "2013-01-20T06:46:24Z" } }, { "pk": 2, "model": "artworks.artwork", "fields": { "updated": "2013-01-17T23:44:26Z" } }, { "pk": 1, "model": "artworks.artwork", "fields": { "updated": "2013-01-17T23:43:22Z" } } ]
How would I make this more human-readable? Thanks!

Based on the comments you've left.. it seems your issue is downstream in the client (e.g. web browser). It is not clear what you mean by stuck in JSON. If you are using JavaScript to parse the JSON, you will need to use JSON.parse() to turn it into a native JavaScript object. If you are using jQuery and the $.ajax() method, you will need to set the mimetype to application/json for it to automatically parse it as JSON.
UPDATE
If you want to control how the JSON data is rendered in the browser, I suggest you parse the JSON response into a native JavaScript object and then iterate over objects and fields you want to render in the page. As an example, using jQuery:
$.ajax({
url: '/some-url/',
dataType: 'json',
success: function(resp) {
var i, k, li, obj, fields;
for (i = 0; i < resp.length; i++) {
obj = resp[i];
// render obj pk or model name here... now iterate over fields
fields = obj.fields;
for (k of obj.fields) {
li = $('<li>').text(k + ': ' + obj.fields[k]);
// append the li to some element..
}
}
}
});

Related

How to render ajax response to view

Here is my predicament: I need to render json response received from controller method. I do this by calling clicking on navbar item "List Articles" which activate method ajaxIndex(). Then tat method makes request to route which in turn call controller method also called ajaxIndex(). That method then gater all articles and sends it as a response. After that, that response i can't control, it just renders raw json ...
Navbar item:
<a class="nav-link" href="/articles" onclick="ajaxIndex(this)"> List Articles </a>
Route:
Route::get('/articles', "ArticlesController#ajaxIndex");
Method in ArticlesController
public function ajaxIndex(Request $request)
{
$var1 = $request->var1;
$var2 = $request->var2;
$elem = $request->elem;
$currUser = auth()->user();
$currUri = Route::getFacadeRoot()->current()->uri();
$articles = Article::orderBy("created_at","desc")->paginate(5);
$html = view('articles.List Articles')->with(compact("articles", "var1", "var2", "elem", "currUser", "currUri"))->render();
//return $request;
return response()->json(["success"=> true, "html" => $html], 200);
//return response()->json(["success"=> $articles,"var1"=> $var1, "var2"=> $var2, "elem"=> $elem, "currUser" => $currUser, "currUri" => $currUri], 200);
}
and here my ajax method
function ajaxIndex(me,formId){
let var1 = "gg";
let var2 = "bruh";
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let url = "/articles";
if(formId){
let form = $("#"+formId).serialize();
console.log(form);
}
$.ajax({
type: "GET",
url: url,
headers:{
"X-CSRF-TOKEN": token
},
data: {/*
var1: var1,
var2: var2,
elem: {
id: me.id ? me.id : null,
class: me.className ? me.className : null,
value: me.value ? me.value : null,
innerHTML: me.innerHTML ? me.innerHTML : null,
}
*/},
success: (data) => {
console.log(data);
$('#maine').html(JSON.parse(data.html));
},
error: (data) => {
console.log(data);
}
});
}
How to render acquired data to particular view?
Now just renders json response alongside html.
My question is how to render response itself and where goes response from controller method. I tried console logging it when route is hit, but there is nothing in console. What is actual approach or what i need to change to achieve this?
Addendum: "For List Articles you will send ajax request to rest api where it returns array of objects(articles)". I assumed i needed to make ajax request, after being sent to appropriate blade, i should now display sent data? Am i getting wrong something? ...
Edit1:
Now when i go to any page in my app, for example:
http://articleapp.test/articles?page=2
it shows json response:
Edit2:
I also modified my ajax method to correctly display current page for article listing. Problem start when try to go to next page.
Here is the code:
function ajaxIndex(me,formId){
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let url = "/articles";
if(formId){
let form = $("#"+formId).serialize();
console.log(form);
}
$.ajax({
type: "GET",
url: url,
headers:{
"X-CSRF-TOKEN": token
},
data: {},
success: (data) => {
console.log(data);
let html = "<div class='container'>";
let articleBody = "";
let pagination = "<ul class='pagination'><li class='page-item'><a class='page-link' href='#'>Previous</a></li>";
if(data.articles.data.length > 0){
for(let i=0;i<data.articles.current_page;i++){
let created_at = data.articles.data[i].created_at.replace(/-/g,"/").split(" ")[0];
html += "<div class='row' style='background-color: whitesmoke;'><div class='col-md-4 col-sm-4'><a href='/articles/"+data.articles.data[i].id+"'><img class='postCover postCoverIndex' src='/storage/images/"+data.articles.data[i].image+"'></a></div><div class='col-md-8 col-sm-8'><br>";
if(data.articles.data[i].body.length > 400){
articleBody = data.articles.data[i].body.substring(0, 400);
html += "<p>"+articleBody+"<a href='/articles/"+data.articles.data[i].id+"'>...Read more</a></p>";
}
else{
html += "<p>"+data.articles.data[i].body+"</p>";
}
html += "<small class='timestamp'>Written on "+created_at+" by "+data.articles.data[i].user.name+"</small></div></div><hr class='hrStyle'></hr>";
history.pushState(null, null, "/articles?page="+(i+1));
}
for(let i=0;i<data.articles.total;i++){
//console.log(data.articles.data[i].id);
pagination += "<li class='page-item'><a class='page-link' href='/articles?page="+(i+1)+"'>"+(i+1)+"</a></li>";
}
pagination += "<li class='page-item'><a class='page-link' href='#'>Next</a></li></ul>";
}
html+="<div class='d-flex' style='margin: 10px 0px;padding-top: 20px;'><div class='mx-auto' style='line-height: 10px;'>"+pagination+"</div></div></div>";
$('#maine').html(html);
//?page=2
},
error: (data) => {
console.log(data);
}
});
}
When i go to next page, it shows json response as i previously stated. Look in the image above. It won't render ...
In this case ajax response should contain only the real content you want to get with the assynchronous request (html tags inside body). Your #maine element should be a div or another structure capable of having html child tags.
Ps.: If you want to render the ajax response like another page by changing header tags and maybe even the http content type then the response should be load inside an iframe tag.
**Edit: ** In pratice, delete the previous content before body tag in the view returned by ajax. And #maine must be a to contain the ajax response.

Create a django url with ajax results

I am using AJAX to refresh a table in my template by using dataTable.
When I get the results from the AJAX call (json) I'm using 'columns' to set every row. In one of the rows, I want to create a Django URL to another view.
What I have tried so far doesn't seem to work
function refreshData(event_ref) {
var table = $('#datatable').dataTable({
'processing': true,
'serverSide': false,
'responsive': true,
'destroy': true,
'ajax': {
'type': "GET",
'url': "{% url 'events:index' %}",
'dataSrc': ""
},
'columns': [
{ "data": "pk", render: function (pk) { return '<input type="checkbox" id="check_' + pk + '" name="check_all">'} },
{ "data": "fields.date_time" },
{ "data": "pk", render: function (pk) { return "<a href='{% url 'events:event' " + pk + "%}'>Click me</a>" }}
],
'order': [[ 2, "desc" ]],
'columnDefs': [ {
'targets': [0, 8], // column index (start from 0)
'orderable': false, // set orderable false for selected columns
}],
'scroller': {
loadingIndicator: true
}
});
}
The problem is in the line
{ "data": "pk", render: function (pk) { return "<a href='{% url 'events:event' " + pk + "%}'>Click me</a>" }}
and what I get is this,
Reverse for 'event' with arguments '(' + pk + ',)' not found. 1 pattern(s) tried: ['events/event/(?P[0-9]+)/']
My urls.py file is this
url('event/(?P<event_id>[0-9]+)/', views.event, name='event'),
and my view.py is this
def index(request):
latest_event_list = events.objects.order_by('-date_time')
if request.is_ajax():
json = serializers.serialize('json', latest_event_list)
return HttpResponse(json, content_type='application/json')
template = loader.get_template('events/index.html')
context = {
'app_name': "events",
'page_name': "real-time",
'latest_event_list': latest_event_list,
'total_events': len(latest_event_list)
}
return HttpResponse(template.render(context, request))
def event(request, event_id):
latest_event_list = events.objects.order_by('-date_time')[:5]
template = loader.get_template('events/event.html')
context = {
'app_name': "events",
'page_name': "archive",
'latest_event_list': latest_event_list,
}
return HttpResponse(template.render(context, request))
How can I create a Django URL with a value from AJAX call?
First of all, passing arguments to the {% url %} template tag isn't done by appending a string, to get the url you want in a template, you do:
{% url 'events:event' event_id=pk %}
Second, any template tag you use in your HTML is interpreted in the back-end once by Django when the HTML page is rendered. That is, before it gets to the browser and javascript starts running (the front-end). So what you're doing makes no sense, because you want javascript to dynamically change the url in the button.
If you look at the source of your HTML in your browser you'll see there's no template tag.
So you have to construct the url in javascript. What you could do is create a javascript variable in your template that is "{% url 'events:event' event_id=1 %}" (which in the HTML file parsed by the browser would be events/event/1 and then using string manipulation replace the "1" with the value of pk.
you catch the error because call tag when the pk is not defined, so you can fix it by using some base url and then replace pk by current value, for example:
{
var base_url = "{% url 'events:event' 0 %}";
var url = base_url.substring(0, base_url.lastIndexOf('/') +1 ) + pk;
return "<a href='" + url + "'>Click me</a>"
}

RestApi call through iron-ajax of polymer

I am developing a polymer app and I want to make a call to the RestApi.
this is the how the request body is
{
"languageId": Presently English is the only supported language. Always 1,
"productCode":"Medicus",
"timeZoneName":"Time zone name of device. For e.g. Asia/Calcutta",
"timeZoneOffset": Time zone offset from UTC in milliseconds. For e.g. IST = 19800000,
"user":{
"firstName":"First name of the user",
"lastName":"Last name of the user",
"middleName":"Middle name of the user",
"password":"Password provided by the user",
"userTypeId":2 = Doctor, 3 = User,
"fields":[
{
"Id":1,
"values":["Mobile number provided by the user”]
}
]
}
}
i am not getting the proper idea of how i should specify these parameters in the params='{}' of iron-ajax element.
Put something like this in your template (I am assuming POST to your rest API, since you said body in your question. If its GET replace body= with params=
<iron-ajax
id="fetchday"
url="/api/fetchday"
handle-as="json"
content-type="application/json"
method="POST"
body="[[params]]"
last-response="{{results}}"
on-response="_gotData"
on-error="_error"></iron-ajax>
And in your polymer element properties
Polymer({
is: 'my-element'
properties: {
params: {
type: Object
}
},
_someFunction: function() {
this.params = //ASSIGN YOUR JSON OBJECT TO PARAMS HERE
this.$.fetchday.generateRequest();
},
_gotData: function(e) {
//response data is in both this.results and e.detail.response
},
_error: function() {
}
});

how to display json data fetched using ajax in each tab

I have a struts 2 action class with a method which returns json data.
I have 8 tabs on my jsp. When a user clicks on a tab, I'd like to make an ajax call to this method. I would like the returned json data to be parsed and decorated with html that can be rendered in this tab.
I'm using jquery tabs to make tabs.
How can I capture the returned json data ? Can I subscribe to some event that jquery publishes ?
How can I process the returned json data ? For e.g.; json data:
{ City : {name="New York", alias="NY", imgPath="filePath/img1.jgp"} }
I would like to extract the name and bold it.
Use the imgPath to define img tag, etc
$(document).ready(function () {
var data = { "City": [{ "name": "New York1", "alias": "NY1", "imgPath": "filePath/img1.jgp" }, { "name": "New York2", "alias": "NY2", "imgPath": "filePath/img2.jgp" }, { "name": "New York3", "alias": "NY3", "imgPath": "filePath/img3.jgp" }, { "name": "New York4", "alias": "NY4", "imgPath": "filePath/img4.jgp"}] };
if (data.City.length > 0) {
$('body').prepend('<div id="tabs1"><ul></ul></div>');
$.each(data.City, function (i, entity) {
$('#tabs1 ul').append($('<li>' + entity.name + '</li>'));
$('#tabs1').append('<div id="tabs1-' + (i + 1) + '"><p>Image Path:' + entity.imgPath + '</p></div>');
});
$("#tabs1").tabs();
}
});​
for live demo see this link: http://jsfiddle.net/nanoquantumtech/ffbx5/
You can capture the returned Json data by passing the data argument to the ajax calls success callback method which will be executed on success. http://api.jquery.com/jQuery.ajax/
You can use jQuery parse.json method and pass the json string to it. http://api.jquery.com/jQuery.parseJSON/
One more thing that your example json string is not looks like valid one. You can check your json is valid or not from this link http://jsonlint.com/ by simply pasting your json data or by pasting the url.

How to pass complex search criteria to jqgrid from query string

I tried code below to pass filter to url which invokes jqgrid. jqGrid still shows all rows, passed filter is not passed to url to retrieve data form server.
How to force jqGrid to filter by filter passed in query string ?
window.open( '/Grid?filters=' + encodeURIComponent(
'{"groupOp":"AND","rules":[{"field":"Name","op":"cn","data":"John"}' ));
You can parse window.location.href and get all parameters which you need. If the URL contains the parameter which you need you can decode it with respect of decodeURIComponent and use like you as need.
The following code can be used for tests. It demonstrate how to decode filters parameter.
if (window.location.href.indexOf('?') < 0) {
// the code will open the current HTML page with additional
// parameter "filters" and reopen the same page with the parameters
window.location = window.location.href + '?' +
$.param({
filters: JSON.stringify({
groupOp: "AND",
rules: [
{field: "Name", op: "cn", data: "John Smith"}
]
})
});
} else {
// decode URL parameters and place in the as properties in the
// object "parameters":
var namedParameters = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'),
parameters = {},
nameAndValue,
i;
for (i = 0; i < namedParameters.length; i += 1) {
nameAndValue = namedParameters[i].split('=');
parameters[nameAndValue[0]] = decodeURIComponent(nameAndValue[1]);
if (nameAndValue[0] === "filters") {
// display the data from the "filters" parameter
var myFilters = $.parseJSON(decodeURIComponent(nameAndValue[1]));
alert(myFilters.rules[0].data);
}
}
}

Resources