How to send JSON request with javascript and receive it in Flask? - javascript

I've written a form that has a n amount of steps, and after parsing the data into string object (to put inside the request body) inside JavaScript, I want to load it up and send it to my Flask backend server.
{
"0": {
"function": "go_to_url",
"values": {
"url": "https://valid.url/"
}
},
"1": {
"function": "refresh",
"values": {
"amount": "5"
}
},
"2": {
"function": "take_screenshot",
"values": {
"name": "screenshotname"
}
},
"3": {
"function": "send_keys_to_element",
"values": {
"xpath": "//*[#value='login']",
"keysToSend": "loginname"
}
},
"4": {
"function": "assert_element_exist",
"values": {
"xpath": "//button[#login]"
}
}
}
This is what I want to send with onclick function within a button inside mentioned form. My Js call looks like this
function submitScenario() {
const steps = Array.from(document.getElementsByClassName('scenario-creation-step'));
const data = {};
for (const c in steps) {
var currentStep_dict = {};
currentStep_dict['function'] = steps[c].childNodes[0].value;
let inputs = Array.from(steps[c].childNodes[1].getElementsByTagName('input'));
var values = {};
for (const i in inputs) {
values[inputs[i].getAttribute('data')] = inputs[i].value;
}
currentStep_dict['values'] = values;
data[c] = currentStep_dict;
}
var dataJson = JSON.stringify(data);
console.log(dataJson);
fetch(window.location.href + 'ed',
{
method: 'POST',
headers: {
'Content-Type':'application/json',
},
body: dataJson,
}
);
}
The form presents itself like that, with url set for 'scenario_added'
<form action="{{ url_for('scenario_added') }}" method="post" name="scenarioForm">
<!-- inputs hidden for data being fetched from flask -->
<input type="hidden" id="scenario_name" value="{{ scenario_details[0] }}" />
<input type="hidden" id="expected" value="{{ scenario_details[1] }}" />
<input type="hidden" id="author_id" value="{{ scenario_details[2] }}" />
<input type="hidden" id="steps_to_show" value="{{ step_names }}" />
<div id="scenario-creation-table" class="scenario-creation-table">
<button type="button" id="add_step">Add a step</button>
<!-- steps show here -->
</div>
<div class="scenario-creation-submitbuttons">
<div></div>
<div></div>
<input type="button" id="download_json" value="Pobierz scenariusz">
<input type="submit" id="submit_scenario_button" value="Dodaj Scenariusz" onclick="submitScenario()">
</div>
The view for scenario_added looks as follows:
#app.route("/scenario_added", methods = ["GET", "POST"])
def scenario_added():
if request.method == "GET":
return '<h6>bad request, it was get for /scenario_added</h6>' #TODO 404
scenario_data = request.json
return render_template('scenario_added.html', data = scenario_data)
Unfortunately, after sending such request, I'm presented with "Bad Request
Did not attempt to load JSON data because the request Content-Type was not 'application/json'."
Even though, when I send the request via POSTMAN on the url, I receive a 200 Code with expected result of the html view containing the data.
How should I rearrange the form or JavaScript function so it will send a request with data gathered from the form?

Related

How to display the values of the attributes of the data queried and retrieved by Ajax call in django

I am trying to query the database based on what the user has clicked on the page and display the data retrieved by it without refreshing the page. I am using Ajax for this. Let me show you the codes
html
<label for="landacq" class="civil-label">Land Acquisation Cases</label>
<input class="civil-category" type="radio" name="civil-cat" id="landacq" value="land acquisation" hidden>
<label for="sc" class="civil-label">Supreme Court</label>
<input class="civil-court" type="radio" name="civil-court" id="sc" value="supreme court" hidden>
<label for="limitation" class="civil-label">Limitation</label>
<input class="civil-law-type" type="radio" name="civil-law-type" id="limitation" value="limitation" hidden>
js
for (i = 0; i < lawTypeInput.length; i++) {
lawTypeInput[i].addEventListener("click", (e) => {
e.preventDefault();
cat = civilCatval;
court = civilCourtval;
lawT = civillawTypeval;
console.log("this is from ajax : ", cat, court, lawT);
$.ajax({
type: "POST",
headers: { "X-CSRFToken": csrftoken },
mode: "same-origin", // Do not send CSRF token to another domain.
url: "civil",
data: {
"cat[]": civilCatval,
"court[]": civilCourtval,
"lawT[]": civillawTypeval,
},
success: function (query) {
showCivilQ(query);
// console.log(data);
},
error: function (error) {
console.log(error);
},
});
});
}
function showCivilQ(query) {
q.textContent = query;
console.log(query);
}
So here for example, if the user the click the radio button in the html, the values are grabbed by in js file and then sent to the url mentioned as a POST request. There these values are use to filter the database and return the objects like this
views.py
def civil_home(request):
if request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
return HttpResponse(query)
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
This is the result I am getting which is correct.
My Question is these objects contain attributes having some values in for eg, title, headnote etc. How can I display these attributes in the html rather than displaying the object names returned as shown in the Image like title of the citation, headnote of the citation etc
A solution could be to return a json object instead of the query resultset; because Ajax works well with json
You need a function that translates a Citation object into a dictionary (change it based on your real attributes). All elements must be translated into strings (see date example)
def citation_as_dict(item):
return {
"attribute1": item.attribute1,
"attribute2": item.attribute2,
"date1": item.date.strftime('%d/%m/%Y')
}
This dictionary must be translated into a json through import json package
def civil_home(request):
if request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
response_dict = [citation_as_dict(obj) for obj in query]
response_json = json.dumps({"data": response_dict})
return HttpResponse(response_json, content_type='application/json')
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
In your HTML page you should be able to parse the response as a normal JSON object
I figured out another way to do it, which is giving me the required results too.
Here I am filtering the values of the query, and then converting it to a list and passing it as a JsonResponse
views.py
def civil_home(request):
if request.method == "POST" and request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.values().filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
result = list(query)
return JsonResponse({"status": "success", "result": result})
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
And then I am recieving the reponse here and iterrating over it to print the attributes in the html
js
for (i = 0; i < lawTypeInput.length; i++) {
lawTypeInput[i].addEventListener("click", (e) => {
e.preventDefault();
cat = civilCatval;
court = civilCourtval;
lawT = civillawTypeval;
console.log("this is from ajax : ", cat, court, lawT);
$.ajax({
type: "POST",
headers: { "X-CSRFToken": csrftoken },
mode: "same-origin", // Do not send CSRF token to another domain.
url: "civil",
data: {
"cat[]": civilCatval,
"court[]": civilCourtval,
"lawT[]": civillawTypeval,
},
success: function (response) {
console.log(response.result);
civilData = response.result;
if ((response.status = "success")) {
$("#queryResult").empty();
for (i = 0; i < civilData.length; i++) {
$("#queryResult").append(
`
${civilData[i].title}
<p>${civilData[i].headnote}</p>
`
);
}
} else {
$("#queryResult").empty();
$("#queryResult").append(
`
<p>No Citations Found</p>
`
);
}
},
error: function (error) {
console.log(error);
},
});
});
}
A csrf_token can be mentioned at the top of the html page and then it can be passed in the header to avoid any conflict.

How to use html form to submit API link to get JSON response

I am creating a Package Tracking Form for a courier company.
Here is my html form
<h2>Track Package</h2>
<form>
<label for="trackingno">Tracking No:</label>
<input type="tel" id="trackingno" name="trackingno">
<input type="submit" value="Submit">
</form>
Company has provided the API Link
http://portal.activecourier.pk/api/v1/packet/00003711/status
When I click this link I get this data
{"packet_id": "0024-00003711", "consignee_name": "Nasir maqbool", "destination": "Lahore", "current_status": {"status": "Assigned to Courier", "datetime": "2020-12-27T17:55:05.414Z", "comment": null}, "statuses": [{"status": "Pickup request sent", "datetime": "2020-12-27T09:55:41.295Z", "comment": null}, {"status": "Booked", "datetime": "2020-12-26T10:13:15.333Z", "comment": null}]}
I want to use html form so visitor enters his package tracking # and get his package details
They usually use jquery to do this
$('#submit').click(function() {
const response = $('#response');
const trackingId = $('#trackingId').val();
let html = '';
$('#trackingId').val('');
response.html('Please Wait');
$.get('http://portal.activecourier.pk/api/v1/packet/'+trackingId+'/status', function(data) {
html += '<div><strong>Packet Id:</strong> '+data.packet_id+'</div>';
html += '<div><strong>Consignee Name:</strong> '+data.consignee_name+'</div>';
html += '<div><strong>Current Status:</strong> '+data.current_status.status+' at '+data.current_status.datetime+'</div>';
let statuses = data.statuses.map((e) => {
return e.status + ' at ' + e.datetime
});
html += '<div><strong>Statuses:</strong> <ul><li>'+statuses.join('</li><li>')+'</li></ul></div>';
response.html(html);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="response"></div>
<input type="text" id="trackingId"/>
<button type="button" id="submit">Submit</button>

Display Axios response data in Vue.JS

I wrote this Vue.JS code to display JSON response received from PHP file in a conversation format. My current code looks like this:
const app = new Vue({
el: "#chatview",
data: {
messages:[],
txtInput: '',
mid:0
},
methods:{
GetBubbleType: function (name){
if(name === "AI")
return "yours messages";
else
return "mine messages";
},
},
mounted(){
axios.post('./ConversationGetter.php',{
function2call: 'getRecord',
id: 1,
}).then( response => {console.log(response.data);
this.data=response.data;
}).catch(error => {});
},
template: `
<div style ="font-family:Open Sans;font-size:16px">
<div v-for="message in messages">
<div class="fade-in">
<div v-bind:class="GetBubbleType(message.name)">
<div class="message last">
<p>{{message.message}}</p>
</div>
</div>
</div>
</div>
<form #submit.prevent="sendMessage('out')" id="person-form">
<p>
<input type="text" placeholder="Enter Your Query Here"style=" border-radius=25px" v-model="txtInput">
</input>
<input type="submit" placeholder="Send"style=" border-radius=25px">
</input>
</p>
</form>
</div>
`
})
The response recieved from PHP is (written on console):
{
"data": [
{
"Modified_Time": "2019-12-13T16:08:36+05:30",
"$currency_symbol": "$",
"Message": "Hey!",
"Created_Time": "2019-12-13T16:08:36+05:30",
"Name": "AI",
},
{
"Modified_Time": "2019-12-13T16:08:27+05:30",
"$currency_symbol": "$",
"Message": "Yo!",
"Created_Time": "2019-12-13T16:08:27+05:30",
"Name": "Me",
},
],
}
The return line of PHP is: echo $result; return $result;
For some reason, it does not show the messages in the chat view.. Where am I going wrong?
Your template is doing a v-for on the messages object from the component's data. However, you're assigning this.data=response.data. That's creating a property data on the component instance, not assigning the messages value.
Instead, just change this.data=response.data to this.messages=response.data.data.
As noted in the comments, your response body contains a data array at the root, and Axios returns the response body in response.data, hence response.data.data is what should be assigned to this.messages.

How to manage .json response data from custom REST in jhipster

I'm creating a new custom RESTful web service (managed with Spring framework) on a Jhipster app that search on objects Request containing a text that I give in input.
I tested the REST call from html and Angular.js and it works fine. The only one problem is that I don't know how could I parse the result in a html page instead of .json format.
My html code (located in "src/main/webapp/app/layouts/navbar/navbar.html") that call REST is this:
<form class="navbar" method="GET" action="/api/search">
<input style="margin-top: 2.8%; margin-right:2px;" class="btn" type="text" name="content" placeholder="Search requests..." />
<input style="margin-top: 2.8%; margin-right:5px;" class="btn btn-primary" type="submit" text="Search" value="Search">
</form>
My "navbarController.js" is this:
(function () {
'use strict';
angular
.module('businessRequestApp')
.controller('NavbarController', NavbarController);
NavbarController.$inject = ['$state', 'Auth', 'Principal', 'ProfileService', 'LoginService', 'Request'];
function NavbarController($state, Auth, Principal, ProfileService, LoginService, Request) {
var vm = this;
vm.isNavbarCollapsed = true;
vm.isAuthenticated = Principal.isAuthenticated;
ProfileService.getProfileInfo().then(function (response) {
vm.inProduction = response.inProduction;
vm.swaggerEnabled = response.swaggerEnabled;
});
vm.login = login;
vm.logout = logout;
vm.toggleNavbar = toggleNavbar;
vm.collapseNavbar = collapseNavbar;
vm.$state = $state;
vm.requests = [];
loadAll();
function loadAll() {
Request.query(function (result) {
vm.requests = result;
vm.searchQuery = null;
});
}
function login() {
collapseNavbar();
LoginService.open();
}
function logout() {
collapseNavbar();
Auth.logout();
$state.go('home');
}
function toggleNavbar() {
vm.isNavbarCollapsed = !vm.isNavbarCollapsed;
}
function collapseNavbar() {
vm.isNavbarCollapsed = true;
}
}
})();
My java REST ("RequestResource.java") is this:
#GetMapping("/search")
#Timed
public ResponseEntity<List<Request>> searchRequest(#RequestParam String content) {
log.debug("REST request to get Request : {}", content);
List<Request> requestsFounded = findByContentContaining(content);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(requestsFounded));
}
When I click the button I receive this .json (that is a list of matching Request that I searched for - based on parameter content give in input):
[ {
"id" : 13,
"requestTitle" : "Titolo",
"content" : "Richiesta",
"creationDate" : "2017-06-23",
"authorUsername" : "admin",
"author" : null,
"referencedTable" : {
"id" : 3,
"usersOnIt" : "",
"name" : "Tavolo 1"
}
}, {
"id" : 14,
"requestTitle" : "Voglio vedere Tiziano Ferro",
"content" : "Mi piacerebbe vedere tiziano per fare ...",
"creationDate" : "2017-06-25",
"authorUsername" : "admin",
"author" : null,
"referencedTable" : {
"id" : 4,
"usersOnIt" : "alfa",
"name" : "Tavolo 3"
}
}, {
"id" : 19,
"requestTitle" : "Titolo",
"content" : "Voglio vedere Marco",
"creationDate" : "2017-06-26",
"authorUsername" : "user",
"author" : null,
"referencedTable" : null
} ]
So, my final question is: how could I translate that .json objects list into an html table?
I've been searching a lot on the web but I found nothing, I hope someone will help me.
Thanks in advice for your time,
Manuel.
You can call a function on form submit and get the json in your vm instance inside your function
HTML
<form class="navbar" ng-submit="vm.getJson()">
<input style="margin-top: 2.8%; margin-right:2px;" class="btn" type="text" name="content" ng-model="vm.content" placeholder="Search requests..." />
<input style="margin-top: 2.8%; margin-right:5px;" class="btn btn-primary" type="submit" text="Search" value="Search">
</form>
<tr ng-repeat="value in json"><td>{{value }}</td></tr>
JS:
vm.getJson=function(){
$http.get("YourUrl",vm.content).then(function(response){
vm.json=response.data;
console.log(response);
})
}

cannot update values comes from dot nation

On my page, I'm rendering form, where data comes from api call
data looks like:
{
"id": 22,
"eventTypeId": 1,
"occuredDate": "2016-05-25T00:00:00",
"title": "event refresh",
"description": "check refresh table",
"studyId": 4,
"statusId": 5,
"severityId": 2,
"priorityId": 3,
"study.id": 4,
"study.name": "Study Y",
"status.id": 5,
"status.name": "Closed"
}
html:
<form style="padding: 15px" ng-submit="submitForm()">
<div class="form-group row">
<div ng-repeat="k in rowKeys | filter: '!id'" ng-model="rowValue">
<label for="rowValue" class="col-sm-2">
{{k | hide:'.name'}}:</label>
<div class=" col-sm-2" >
<input class="form-control rowValue" id="rowValue" ng-model="rowData[k]" ng-disabled="isDisabled()"/>
</div>
</div>
</div>
<button type="submit" class="btn btn-default" ng-if="rowData" >Submit</button>
</form>
My problem is when I edit fields such as "title" or "description", everything works fine, but when I try to edit fields such as "study.name" or "status.name" it just refresh the page and doesn't put any updates. Angular watch works fine and I see in console that value has been updated, so could anybody help me to find my mistake?
My submit function:
$scope.submitForm = function() {
$scope.$watch('rowData', function(newValue, oldValue) {
console.log('being watched oldValue:', oldValue, 'newValue:', newValue);
}, true);
$http({
method : 'PUT',
url : $scope.globalUrl + $scope.id,
data : $scope.rowData //form
})
.then(function (res) {
return res;
})
.then(function (){
$('#table').bootstrapTable('refreshOptions', {
'url': $scope.globalUrl
});
})
};
My load function
$scope.load = function (){
$http({
method: "GET",
url: $scope.globalUrl + $scope.id
}).then(function success(response) {
$scope.rowData = response.data;
}, function error(response) {
console.log("It has happend error in response")
});
}
When you have a dot in your key you need to use bracket notation:
obj['study.name']
Here is a quick example:
https://jsbin.com/fihogu/1/edit?js,console

Categories

Resources