How to get passed JSON Data on Ajax Error? - django

I am using Django and Ajax.
Im my view I have:
class MainView(View):
def get(self, request):
if not request.is_ajax():
return render(request, "main.html")
# hard coded both options for testing
return JsonResponse({"data": "xyz"}, status=400)
# return JsonResponse({"data": "xyz"}, status=200)
my ajax function looks like:
$("#start_calculation_button").click(function () {
$.ajax({
url: "/",
type: 'get',
data: {
...
},
success: function (response) {
console.log(response.data);
},
error: function (response) {
console.log(response.data);
}
})
})
But only the success function works? While the error part just gives back undefined
Any idea's why it is that way?
How can I fix it?

The parameters of success and error are different, in case of a success, these parameters are result, status, and xhr whereas for error, the parameters are xhr, status, and error. You thus should parse the xhr data with:
$("#start_calculation_button").click(function () {
$.ajax({
// ⋮
success: function (response) {
console.log(response.data);
},
error: function(xhr) {
var err = JSON.parse(xhr.responseText);
console.log(err.data);
}
})
})

Related

Reload django template into ajax response

is it possible to reload a Django template after an ajax call?
This is my code.
script.js
$('.test').click(function(){
var platform = $('#testModal').attr('test-attr');
$.ajax(
{
type:"POST",
url:"test",
headers: {
'X-CSRFToken': TOKEN
},
dataType: "json",
cache : false,
processData : false,
contentType : false,
data: string,
success: function(data) {
location.reload();
}
});
});
view.py
return render(request, "user_interface/index.html", {'my_var': 'abc', 'my_var_2': 'cde'})
I tried to use return HttpResponse(json.dump({'res': 'Ok', 'err': None}), content_type = "application/json") but when i reload the page it fails.

ValueError: Cannot use None as a query value django ajax

I want to show the dropdown list with data response via Ajax call. Everything is working fine but I am getting this ValueError: Cannot use None as a query value error.
view:
def load_brand(request):
if request.is_ajax():
term = request.GET.get('term')
brand = Brand.objects.all().filter(brand__icontains=term)
return JsonResponse(list(brand.values()), safe=False)
ajax:
$('#id_brand').select2({
ajax: {
url: '/brand/ajax/load-brand/',
dataType: 'json',
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {id: item.id, text: item.brand};
})
};
}
},
minimumInputLength: 1
});
In your ajax call you have not send the data i.e : which user type inside select2 and you are accessing them i.e : request.GET.get('term') which is empty so your .filter(brand__icontains=term) giving you error because term value is null.
Instead you can add below as well in your ajax call :
$('#id_brand').select2({
ajax: {
url: '/brand/ajax/load-brand/',
dataType: 'json',
data: function(params) {
var query = {
term: params.term, //this will be paass
type: 'public' //optional..
}
// Query parameters will be ?term=[values]&type=public
return query;
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {
id: item.id,
text: item.brand
};
})
};
}
},
minimumInputLength: 1
});
Also , at your server end you can check if the term has any value i.e :
if term:
brand = Brand.objects.all().filter(brand__icontains=term)
For more information check this

How to use JS's parameters to views.py (Django)

JS
$(function(){
var count=1;
$("#btn").click(function(){
count++;
})
})
views.py
def setparam(request):
counts=range(1,count)
eg.
Like this I want use JS's count to view.py .How can I get it ,is it possible?
You need send this to server.
I guess you ajax for your example.
JS
function send_cont(cont) {
$.ajax({
url: '{% url "your_app.views.your_view" %}',
type: "GET",
data: {
cont: cont
},
success: function (json) {
//Something
},
error: function (json) {
//Something
}
});
}
View
def your_view(request):
cont = request.GET.get('cont'))
#More code

Django gives 400 Bad request error in image upload using ajax

I am using quill editor to upload an image and the an ajax function is used to send the image to views.py.
This is the python function for uploading the image.
views.py
def upload_image(request):
if request.method == 'POST':
handle_uploaded_file(request.FILES.get('file'))
return HttpResponse("Successful")
return HttpResponse("Failed")
def handle_uploaded_file(file):
with open('upload/', 'wb+' ) as destination:
for chunk in file.chunk():
destination.write(chunk)
This is the ajax request:
function upload(file, callback) {
console.log('called');
var formData = new FormData();
formData.append('file', file);
$.ajax({
url : '{% url 'dashboard:upload_image' %} ',
type : 'POST',
data : formData,
contentType: 'multipart/form-data',
headers: { "X-CSRFToken": $.cookie("csrftoken") },
processData: false,
success: function(data) {
console.log('success');
callback(data.url)
}
});
}
Function calling upload() :
function(value) {
let fileInput = this.container.querySelector('input.ql-image[type=file]');
if (fileInput == null) {
fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('accept', 'image/*');
fileInput.classList.add('ql-image');
fileInput.addEventListener('change', () => {
if (fileInput.files != null) {
upload();
}
});
this.container.appendChild(fileInput);
}
fileInput.click();
}
}
Error in string
with open('upload/', 'wb+' ) as destination:
Wrong path. Set the file name.

karma mock promise response

I have the following factory that I'd like to test:
angular
.module('enigma.authFactory', [])
.factory('authFactory', authFactory);
authFactory.$inject = ['$http'];
function authFactory($http){
function doesUserExist(email){
return $http.post('/doesUserExist', email)
.success(function(data){
if(data !== 'user exists'){
return false;
} else {
return true;
}
});
}
}
So I wrote the following test:
describe('Auth Service Tests', function() {
var $httpBackend, defer, doesUserExistReqHandler;
beforeEach(inject(function(_$httpBackend_, $injector, $q) {
$httpBackend = _$httpBackend_;
defer = $q.defer();
doesUserExistReqHandler = $httpBackend.when('POST', '/doesUserExist').respond(defer.promise);
}));
describe('authFactory.doesUserExist()', function() {
it('should return true is a user exists', function() {
user = {
email: 'bwayne#wayneenterprise.com'
};
$httpBackend.whenPOST('/doesUserExist', user).respond('user exists');
var doesUserExist = authFactory.doesUserExist(user);
$httpBackend.flush();
expect(doesUserExist).toEqual(true);
});
});
});
I checked inside the authFactory.doesUserExist function and I am correctly getting the data set to 'user exists' which routes the function to return true. However in the unit test authFactory.doesUserExist is being set to the following object.
Expected Object({ $$state: Object({ status: 1, pending: undefined, value: Object({ data: Object({ $$state: Object({ status: 0 }) }), status: 200, headers: Function, config: Object({ method: 'POST', transformRequest: [ Function ], transformResponse: [ Function ], paramSerializer: Function, url: '/doesUserExist', data: Object({ email: 'bwayne#wayneenterprise.com' }), headers: Object({ Accept: 'application/json, text/plain, */*', Content-Type: 'application/json;charset=utf-8' }) }), statusText: '' }), processScheduled: false }), success: Function, error: Function }) to equal true.
I'm thinking the issue is that the test isn't resolving the promise properly and so I'm setting the res variable before authFactory.doesUserExist has returned true.
How would I go about fixing this?
So a few things needs to happen to get your code to work with what you have.
Here is a demo http://plnkr.co/edit/4GvMbPJgc0HcJcgFZ4DL?p=preview
Your service (factory) needs to return an object.
You are not returning a promise after your $http post.
I recommend you use the $q service.
In the testing
You need to import your module.
Be sure to inject your service
You should remove $httpBackend.when('POST', '/doesUserExist').respond(defer.promise); since it is not accomplishing anything and it is actually getting it confused in other $httpBackend.whenPost.
You should be asserting the response data instead of the promise, because authFactory.doesUserExist(user) returns a promise.
Code:
var doesUserExist = authFactory.doesUserExist(user)
.then(function (data) {
responseData = data;
});
$httpBackend.flush();
expect(responseData).toEqual(true);