Bad request error in Flask while request names generated with javascript - javascript

I'm creating an app to calculate a projection of the transit given the years and some other values, first I created a script in javascript where depending on if the user decide to add a new type of vehicle a new div is created with unique ids and names and ofcourse the data the user introduced, for showing the final result i'm using ajax, the problem comes when i tried to access the data via flask, i'm getting a bad request from the names of each vehicle like if they did not exist, but the page is actually displaying them (hope you understand my english and my problem :) )
I've tried giving a specific name (a1) an then tried to take the value in flask but i still can#t make it work.
Python
#app.route("/pavimentos/calculoTransito" , methods=['POST'])
def calculoTransito():
direc = float(request.form["direc"])
zr = float(request.form["zr"])
years = float(request.form["years"])
tc = float(request.form["direc"])
vehicles = int(request.form["vehicles"])
car1 = request.form.get("a1", None)
if car1==None:
print("No funciona")
else:
print("Funciona")
always get "No funciona"
Javascript
countClicks = 0
lista_vehiculos = []
function addVehicle(){
countClicks += 1;
//var automovil = document.getElementById("automovil").value
var fd = document.getElementById("damage_factor").value
var currentType = document.getElementById("vehicleType")
if(currentType.value == 1){
var icon = "<h2 class='pt-4'><i class='fas fa-car text-secondary'></i></h2>";
var tipoVehiculo = "Automóvil";
}
... More code for select the currentType ...
var vehicleStyle = "<div><input id=a" + countClicks + "name=a" + countClicks + "value=" + fd + "></div>"
lista_vehiculos.push(vehicleStyle)
var vehicle = document.getElementById("vehiclesContainer").innerHTML += lista_vehiculos[countClicks-1]
document.getElementById("vehicles").value = countClicks
}
AJAX part
$(document).ready(function(){
$('form').on('submit', function(event){
$.ajax({
data:{
direc: $('#direc').val(),
zr: $('#zr').val(),
years: $('#years').val(),
tc: $('#growingRate').val(),
vehicles: $('#vehicles').val(),
car1: $('#a1').val()
},
type: 'POST',
url: '/pavimentos/calculoTransito'
})
.done(function(data){
if (data.resultado){
$('#resultado').text(data.resultado).show()
}
})
event.preventDefault();
});
});

You're not submitting a form, you're sending JSON. The initial event might be the submission of a form, but your AJAX uses event.preventDefault() and does not end up submitting a traditional serialized form. You can't use car1 = request.form.get("a1", None) here.
Firstly, you should correct your AJAX to add a contentType:
$(document).ready(function(){
$('form').on('submit', function(event){
$.ajax({
data: JSON.stringify({
direc: $('#direc').val(),
zr: $('#zr').val(),
years: $('#years').val(),
tc: $('#growingRate').val(),
vehicles: $('#vehicles').val(),
car1: $('#a1').val()
}),
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: '/pavimentos/calculoTransito'
})
.done(function(data){
if (data.resultado){
$('#resultado').text(data.resultado).show()
}
})
event.preventDefault();
});
});
And then you need to change your Flask method from request.form to request.json. So the Flask side would look something like:
#app.route("/pavimentos/calculoTransito" , methods=['POST'])
def calculoTransito():
req = request.json
direc = float(req["direc"])
zr = float(req["zr"])
...
car1 = req.get("a1", None)
if car1 is None: # None is a singleton, you shouldn't use == here
print("No funciona")
else:
print("Funciona")
LATE EDIT
This can't work because calculoTransito does not actually return anything, so Flask will throw an error from that alone. Your view function actually has to return something other than an implicit None.

Related

Ajax call won't navigate to a new view

I've created an application using codeigniter 3 that gets quizzes stored in the SQL database using a model and populate in the view using ajax and jquery.
Below is the code for populating data inside a div.
$(document).ready(function() {
$.ajax({
url: "/CW2/ASSWDCW2/cw2app/index.php/Leaderboard/quiz",
method: "GET",
dataType: "json"
}).done(function(data) {
$('#modtable tr').remove(); // clear table for new result
var quizzes = data.allQuizzes;
alert(quizzes.length);
var i;
for (i = 0; i < quizzes.length; i++) {
quiz = quizzes[i];
var block = ' <div id="quizMainBox"><h1>' + quiz.quizName + '</h1><br/><h3>' + quiz.creatorName + '<button onclick="myFunction(\''+quiz.quizId+'\')">Try it</button>'+'</h3></div>'
$('#allQuizBox').append(block);
}
});
return false;
// });
});
Below are 3 quizzes populated in the view.
What I want to do is when the user clicks on the "try it " button, I want the user to be directed to the "single_quiz_view" using the quiz id. So I wrote this ajax function (myFunction) below the above code.
function myFunction(quizId) {
// console.log("heyyyy");
// document.getElementById("demo").innerHTML = "Welcome"+quizId ;
$.ajax({
url: "/CW2/ASSWDCW2/cw2app/index.php/Quiz/loadQuiz/",
method: "POST",
}).done(function(data) {
alert("heyyy")
});
return false;
}
where Quiz is the controller name and loadQuiz is the function calling the "single_quiz_view"
//Quiz Controller
public function loadQuiz()
{
// $quizId = $this->uri->segment(3);
$this->load->view('quiz/single_quiz_view');
}
My problem is,
When I click on the "try it button", I get the alertBox inside the done function. I get the status code as 200 but still wont navigate to "single_quiz_view".Console wont give any errors.Please help

Calling Django Function from JS Ajax not working

I am trying to call a python function that calculates and converts some number input from a user form.
I have an onclick button event to call the following JS function
$.ajax({
type: "POST",
url:"/calc_ha_range/",
dataType: 'json',
data: {'ra_deg' : ra_deg, 'dec_deg': dec_deg, 'glon_deg': glon_deg, 'glat_deg': glat_deg},
success: function(data) {
jsonData = JSON.parse(data);
ha_start.setAttribute('min', jsonData.min);
ha_start.setAttribute('max', jsonData.max);
ha_end.setAttribute('min', jsonData.min);
ha_end.setAttribute('max', jsonData.max); // data.min = minimum val for HA range
}
})
I then have a django url mapping in the form of
import home.views, sensitivity_radec_astro.views,sensitivity_radec_astro_show.views, sensitivity_map.views, sensitivity_map_show.views, sensitivity_radec_vs_freq.views, sensitivity_radec_vs_freq_show.views, sensitivity_radec_vs_lst.views, sensitivity_radec_vs_lst_show.views, sensitivity_vs_freq.views, sensitivity_vs_freq_show.views, sensitivity_vs_lst.views, sensitivity_vs_lst_show.views, utils.sensitivity_db
urlpatterns = [
path('', home.views.load),
path('sensitivity_radec_astro/', sensitivity_radec_astro.views.load),
path('sensitivity_radec_astro_show/', sensitivity_radec_astro_show.views.sensitivity_radec_astro_show),
path('sensitivity_map/', sensitivity_map.views.load),
path('sensitivity_map_show/', sensitivity_map_show.views.sensitivity_map_show),
path('sensitivity_radec_vs_freq/', sensitivity_radec_vs_freq.views.load),
path('sensitivity_radec_vs_freq_show/', sensitivity_radec_vs_freq_show.views.sensitivity_radec_vs_freq_show),
path('sensitivity_radec_vs_lst/', sensitivity_radec_vs_lst.views.load),
path('sensitivity_radec_vs_lst_show/', sensitivity_radec_vs_lst_show.views.sensitivity_radec_vs_lst_show),
path('sensitivity_vs_freq/', sensitivity_vs_freq.views.load),
path('sensitivity_vs_freq_show/', sensitivity_vs_freq_show.views.sensitivity_vs_freq_show),
path('sensitivity_vs_lst/', sensitivity_vs_lst.views.load),
path('sensitivity_vs_lst_show/', sensitivity_vs_lst_show.views.sensitivity_vs_lst_show),
path('calc_ha_range/', utils.sensitivity_db.calc_hour_angle_range)
]
which refers to the following python function
def calc_hour_angle_range( request ):
geo_lat = EarthLocation.from_geodetic(lon="XXXX",lat="XXXX",height=XXXX).lat.value
if request.method == "POST":
ra_deg, dec_deg, glon_deg, glat_deg = request.POST["ra_deg"], request.POST["dec_deg"], request.POST["glon_deg"], request.POST["glat_deg"]
tan_geo_lat = math.tan( geo_lat*(math.pi/180.00) )
tan_dec = math.tan( dec_deg*(math.pi/180.00) )
cos_ha = -tan_dec * tan_geo_lat
ha_rad = math.acos( cos_ha )
ha_deg = ha_rad*(180.00/math.pi)
ha_h = ha_deg/15.00
output = {'min': -math.fabs(ha_h), 'max': +math.fabs(ha_h)}
My issue is when the ajax call takes place in the onClick function I get an error in the console saying 404: mysite.com/calc_ha_range/ not found
I have taken over this project from another amateur developer so my understanding of ajax and django is quite fragmented

django with ajax like and unlike

I , so I wrote an application with django and implemented a like and unlike function but I noticed that it works fine but the problem is if a user likes a post and decides to unlike it , the likes . count would go to -1 instead of 0 and thus it is possible for a two users like to become 3 but if one of the two unlikes it then it goes to 1 . below is my jQuery function
jQuery
$(document).ready(function(){
function updateText(btn, newCount, verb){
btn.text(newCount + " " + verb)
}
$(".like-btn").click(function(e){
e.preventDefault()
var this_ = $(this)
var likeUrl = this_.attr("data-href")
var likeCount = parseInt(this_.attr("data-likes")) | 0
var addLike = likeCount + 1
var removeLike = likeCount - 1
if (likeUrl){
$.ajax({
url: likeUrl,
method: "GET",
data: {},
success: function(data){
console.log(data)
var newLikes;
if (data.liked){
updateText(this_, addLike, "Unlike")
} else {
updateText(this_, removeLike, "Like")
// remove one like
}
}, error: function(error){
console.log(error)
console.log("error")
}
})
}
})
})
view.html
<p><a class='like-btn' data-href='{{ obj.get_api_like_url }}' data-likes='{{ obj.likes.count }}' href='{{ obj.get_like_url }}'>{{ obj.likes.count }} Like</a></p>
View.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
class PostLikeAPIToggle(APIView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, slug=None, format=None):
# slug = self.kwargs.get("slug")
obj = get_object_or_404(Post, slug=slug)
url_ = obj.get_absolute_url()
user = self.request.user
updated = False
liked = False
if user.is_authenticated():
if user in obj.likes.all():
liked = False
obj.likes.remove(user)
else:
liked = True
obj.likes.add(user)
updated = True
data = {
"updated": updated,
"liked": liked
}
return Response(data)
if any other part of my code is required I would gladly supply it. Thanks
You haven't updated the data-likes when the user has liked or unliked a post. Since, the page won't refresh the tag containing attribute data-likes with value {{ obj.likes.count }} will never re-render on UI.
if (data.liked) {
// ...
} else {
// ...
}
// update the `data-likes`
this_.data('likes', likeCount);
Note: You can use .data() method to access the data-* attributes, rather than using attr.
Ref: jQuery .data() docs

Passing data that is coming from a server, from one page to another in javascript without using forms

I do not have much grip on javascript and having problemswith it.
My data is coming from a server and the user when clicks on an item is redirected to a new page which has that items all details. The problem is when a user clicks on an item,how to send the data from one page to the next.
No php is used. javascript ajax jquery used and data coming from json
this is format and when user clicks on play button a new age should be displayed where the data is to be shown to user.
Template={"Big_Display_Template": '{{#items}}<input type="hidden" name="guid" value="{{id}}"><div class="hero"
style="background-image:url({{videoStillURL}})"><div class="hero-content"><br>
<h2>{{name}}</h2> <p>{{shortDescription}}</p> <div class="hero-links"><a href="Watch_Live.html"
onclick="PassDataToNextPage({{name}},{{id}},{{shortDescription}});">
Play<span class="genericon genericon-play"> </span></a></div>
<div class="hero-links-fav"><a href="#">Favourite<span class="genericon genericon-fav">
</span></a></div></div></div>{{/items}}'
}
This is my function PassDataToNextPage()
function PassDataToNextPage(name,guid,Description)
{
var url = 'Watch_Live.html';
$.ajax({
url: url,
type: 'POST',
data: 'name=' + name + '&guid=' + guid + '&shortDescription=' + Description,
success: function(result) {
dataUrl=data;
}
});
return window.location+"/"+dataUrl;
}
I know this is wrong but how to make it right? thanks a lot in advance
The problem lies in the return window.location+"/"+dataUrl; line: the redirect should be done inside the success function because it will be called when the request is completed:
function PassDataToNextPage(name,guid,Description)
{
var url = 'Watch_Live.html';
$.ajax({
url: url,
type: 'POST',
data: 'name=' + name + '&guid=' + guid + '&shortDescription=' + Description,
success: function(result) {
dataUrl = data;
window.location = window.location + "/" + dataUrl;
}
});
}
In the template you must add return false in the onclick attribute to avoid the browser following the link interrupting your handler:
<a href="Watch_Live.html" onclick="PassDataToNextPage({{name}},{{id}},{{shortDescription}});return false">
You can pass key:value data via url GET parameters.
For example: if you want to pass data to this page: Watch_Live.html, you can do something like:
<button>Pass data</button>
To parse the parametesr in the other page, read this SO answer to a similar question.
https://stackoverflow.com/a/901144/4440845
Look like you want to pass data and go to the next page with the data, you don't need ajax to achieve. Simply:
function PassDataToNextPage(name,guid,Description)
{
var url = 'Watch_Live.html';
window.location.href = url + '?name=' + name + '&guid=' + guid + '&shortDescription=' + Description;
}
Comment:
You can use:
< a onclick="PassDataToNextPage({{name}},{{id}},{{shortDescription}});">Play< /a>
The click event will be handled by the function PassDataToNextPage in onclick.
Assuming you use PHP in your next page, you can fetch the data
$name = $_GET['name'];
$guid = $_GET['guid'];
$shortDesc = $_GET['shortDescription'];

Ajax success function issue

My javascript looks like that.
There are some problems that I can't figure out, where I did mistake
#status_message doesn't show generated message
$("#status").className = 'fail'; doesn't override current class
var message=$("#status_message"), form=$("#bcscan"), ids=$('#itemids'),proctype, destination, counter=0, tenWordCounter = 0, autoPostInterval=null, errorcount=0, successcount=0;
function ajaxPost() {
formData = form.serialize()+'&process=Scan';
formUrl = form.attr('action');
formMethod = form.attr('method');
$.ajax({
url: formUrl,
type: formMethod,
dataType: "json",
data: formData,
success: function (data) {
var now = new Date();
if(data.err_detected==="yes")
{
if(data.errors.indexOf(",") != -1)
errorcount=errorcount+data.errors.split(",").length;
else errorcount=errorcount+1;
$("#status").className = 'fail';
message =errorcount+" errors found";
$('#errors').prepend(data.errors).slideDown("slow");
}
$('#success').prepend(data.success).slideDown("slow");
if(data.success.indexOf(",") != -1)
successcount=successcount+data.errors.split(",").length;
else successcount=successcount+1;
message +="Last submitted:"+now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
$("#status_message").text(message);
}
});
}
Here is page in action
If you want to test, please choose some option from selects like, output from db, ebay.fr and press "scan". Enter 10 digits seperated by comma try 41,42 (they exist in db tables) too between them. After 10th digit it will post textarea via ajax.
For the message, you've declared a jQuery object pointing at the element:
var message = $('#status_message'), ...
but then you're overwriting it with a string:
message = errorcount + ' errors found';
You should be calling:
message.text('some string...')
to change its contents.
For the class change, the correct syntax is:
$("#status").addClass('fail');
How about
$('#status').attr('class','fail');
This will override the current class.
did you try this?? $("#status").addClass( 'fail');

Categories