Why Autocomplete form in django doesn't work - javascript

I have been trying several different kind of code for an autocomplte form with Django
Im new on this but here are the code:
Views.py
def search_ifsc(request):
try:
q = request.GET.get('q', '').capitalize()
search_qs = InfoTrabajadores.objects.filter(documento__startswith=q)
results = []
print(q)
for r in search_qs:
dict_data = {'documento':r.documento,'nombres':r.nombres,'info':{
'num_emergencia':r.num_emergencia,
'prov_salud':r.prov_salud,
'prov_salud_trabj':r.prov_salud_trabj,
'rh':r.rh}}
results.append(dict_data)
data = json.dumps(results)
except Exception as e:
data = 'fail'+ f'\n{e}'
mimetype = 'application/json'
return HttpResponse(data, mimetype)
This in the endpoint to filter te data with the document that came from the model
Inside the HTML document i have this:
<script type='text/javascript'>
fetch('http://127.0.0.1:8000/ajax/search/')
.then((response) => response.json())
.then((data) => {
document.getElementById('nombre').value = data.nombres;
document.getElementById('num_emergencia').value = data.num_emergencia;
document.getElementById('prov_salud').value = data.prov_salud;
document.getElementById('prov_salud_trabj').value = data.prov_salud_trabj;
document.getElementById('rh').value = data.rh;
} )
And the urls.py
urlpatterns = [
path('ajax/search/' , search_ifsc, name='search_view'),
]
This is how the site looks with the actual code
I've been trying change de model and how the query works, but nothing change the response in the site

Related

How to render RapidAPI data on another HTML page?

I am new to JavaScript and this is my first question here. I've been trying for week to render my RapidApi data on another HTML page. I made search form on my index page and then put its values as my api call parameters in order to influence my API response. I used fetch to do so. The issue is that my API data keeps rendering on the same index page which is understandable since I don't know how to render it on a separate page. This also means that my CSS styling options are limited since I cannot design API data as I want without messing up my index page. If you have any sort of solution that is not way too complicated I would really appreciate your help.
Here is part of my code:
const input = document.getElementById(`location`);
const guests = document.getElementById(`guests`);
const check = document.querySelectorAll(".date");
let id;
document.getElementById(`submit`).addEventListener(`click`, function (e) {
e.preventDefault();
locationId();
});
async function locationId () {
let hotelId = input.value;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': '//API key goes here',
'X-RapidAPI-Host': 'tripadvisor16.p.rapidapi.com'
}
};
let response = await fetch(`https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchLocation?query=${hotelId}`, options);
if (!response.ok) throw new Error(`Woops something went wrong`);
let data = await response.json();
let geoId = await (data.data[0].geoId);
id= parseInt(geoId);
return (fetch(`https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchHotels?geoId=${id}&checkIn=${check[0].value}&checkOut=${check[1].value}&pageNumber=1&adults=${guests.value}currencyCode=USD`, options))
.then(response => response.json())
.then(data => {
let list = data.data.data;
displayObjectElements(list)
function displayObjectElements (object) {
let display = ``;
let price = ``;
object.forEach(element => {
display+= `<div class = "objectResults">
<ul class="hotel__lists">
<li><h2 class = "title">${element.title}</h2></li>
<li><img class= "hotels--photo "src="${element.cardPhotos[0].sizes.urlTemplate.split("?")[0] + `?w=500&h=500`}" alt=image--photo/></li>
<li><p>Ranking:${element.bubbleRating.rating}&#9734 out of 5&#9734</p></li>`
if(!element.priceForDisplay) {
display+= `<li><p>There is no price to display</p></li>`
display+= `<li><button class="booking-btn">Click to book</button></li>`
} else {
price =element.priceForDisplay.substring(1);
price= parseInt(price);
// console.log(price);
display+= `<li><p>Price: $${price} in total</p></li>`
display+= `<li><button class = "booking-btn">Click to book</button></li>
</ul>
</div>`
// console.log(display);
}});
document.body.innerHTML = display;
}
})
.catch(err => console.error(err));
}
I already tried with localStorage and sessionStorage but as a newbie I am just now sure how to put the whole API data in storage. Also, I desperately tried with window.location object as well but as I assumed that did nothing but open a new tab. Again, thanks in advance for any help!

Fetch API prints promise in incorrect order

I am trying to fetch the HTML script of two webpages using their URLs. This is my code:
const links = ["url1" : "https://.......", "url2" : "https://......"];
var responses = [];
for(const [key,value] of Object.entries(links)){
let resp = fetch('https://api.codetabs.com/v1/proxy?quest='+value)
responses.push(resp);
}
Promise.all(responses)
.then( htmlfiles =>{
htmlfiles.forEach(file=>{
file.text().then(function(data){
gethtmldata(data);
})
})
})
In my function gethtmldata, I am parsing this data in HTML format:
function gethtmldata(html_data){
var parser = new DOMParser();
var htmldoc = parser.parseFromString(html_data, "text/html");
console.log(htmldoc); //shows data of url2, then url1
}
To my utter surprise, the data of url2 gets printed first, then url1. Why?
It should show the html data of url1 then url2. How do I fix this?
The iterations of your for loop aren't paused when you do file.text().then(function(data){...}. Instead, your loop fires off multiple .text() calls which will complete sometime in the future, with no guaranteed order on which ones will complete first.
You should .push() a Promise that resolves to your .text() data instead when you create resp:
const links = {"url1" : "https://.......", "url2" : "https://......"};
const urls = Object.values(links);
const responses = [];
for(const value of urls){
const txtPromise = fetch('https://api.codetabs.com/v1/proxy?quest='+value).then(resp => resp.text());
responses.push(txtPromise);
}
Promise.all(responses)
.then(htmlData => {
htmlData.forEach(data=>{
gethtmldata(data);
});
});
You can refactor the above by using .map() and async/await like so:
async function fetchHTMLData(urls) {
const promises = urls.map(async url => {
const resp = await fetch('https://api.codetabs.com/v1/proxy?quest='+url);
return resp.text();
});
return Primise.all(promises);
};
async function processHTMLData() {
const links = {"url1" : "https://.......", "url2" : "https://......"};
const urls = Object.values(links);
const htmlArr = await fetchHTMLData(urls);
htmlArr.forEach(htmlStr => {
gethtmldata(htmlStr);
});
}

Fetch new data from sqlite database on reload

I managed to get sensor data into a sqlite3 database. Every 2 minutes new values appear in the database. Now I want to display it with chart.js and therefore make use of sql.js
The code I use is:
const config_sqljs = {
locateFile: filename => (
'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.5.0/sql-wasm.wasm'
)
}
const sqlPromise = initSqlJs(config_sqljs)
const dataPromise = fetch((
'/sensors.db'
))
.then(res => res.arrayBuffer())
Promise.all([sqlPromise, dataPromise])
.then(([SQL, buf]) => {
const db = new SQL.Database(new Uint8Array(buf))
//const res = db.exec('select time_,temp,humi from sensors where topic=\"/x/sensors\"')
const res = db.exec('select time_,temp,humi from sensors where topic =\"/y/sensors\" and (date=\"29.11.2021\" or date=\"30.11.2021\" or date=\"01.12.2021\");')
const values = res[0].values;
let labelx = values.map((arr) => arr[0]);
let y = values.map((arr) => arr[1]);
let y2 = values.map((arr) => arr[2]);
})
It works well at first, but then I realized that the values in the arrays labelx, y, and y2 are not the newest one, they lack beheind, about half a day. The new values alwasy appear in the database. I think it has todo something with Promise.all() and .then but unfortunally I don't know much about js. The code is executet each time the site loads or reloads, even I I use Strg+F5 to force a complete, uncached reload it stays the same. Can you help me? Thanks!
=== EDIT ===
I adapted your suggestion:
const dataPromise = fetch((
'/db.db', {
method: "GET",
"cache-control": "no-store"}
))
.then(res => res.arrayBuffer())ยด
Sadly I get the error:
Uncaught (in promise) Error: file is not a database
the relevant line:
const res = db.exec('select x from db;')
Fetch might be caching the responses. Try:
fetch('/sensors.db', {
method: "GET",
"cache-control": "no-store"
})

How do i execute fetch() before other funcitons?

I'm currently learning JavaScript, and has been playing around with API's (Yahoo Finance in this example).
The goal is to update a table of values with a specific stock's financial data - but I need to fetch the data, before it updates the data. Thought I could use await/async as shown, but it doesn't work.
Any pointers?
let stats;
let inputSymbol;
let stockName;
let stockSymbol;
let stockPrevClose;
let stockOpen;
let stockMarketCap;
let stockDayHigh;
function getStockStatistics(){
//Get symbol from input field
inputSymbol = document.getElementById("inputSymbol").value;
console.log(inputSymbol);
request();
updateStockTabel();
}
//Fetch data from Yahoo Finance API based on variables
const request = async () => {
const response = await fetch(`https://apidojo-yahoo-finance-v1.p.rapidapi.com/stock/v2/get-financials?symbol=${inputSymbol}&region=US`, {
"method": "GET",
"headers": {
"x-rapidapi-key": "---",
"x-rapidapi-host": "---"
}
});
const data = await response.json();
stats = data;
console.log(data);
}
//Update statistics in table based on values from Yahoo Finance JSON object
function updateStockTabel() {
//Change properties
stockPrevClose = stats.summaryDetail.previousClose.raw;
stockOpen = stats.summaryDetail.open.raw;
stockMarketCap = stats.summaryDetail.marketCap.fmt;
stockDayHigh = stats.price.regularMarketDayHigh.fmt;
stockName = stats.price.longName;
stockSymbol = stats.meta.symbol;
//Connect document properties with variables
document.getElementById("stocPrevClose").innerText = stockPrevClose;
document.getElementById("stockOpen").innerText = stockOpen
document.getElementById("stockMarketCap").innerText = stockMarketCap;
document.getElementById("dayHigh").innerText = stockDayHigh;
document.getElementById("stockName").innerText = stockName;
document.getElementById("stockSymbolOutput").innerText = stockSymbol;
}
You have 2 options mainly: leave your code exactly as it is now, but use this to wait to run updateStockTabel :
request().then(() => updateStockTabel());
OR change your getStockStatistics to an async function to do something pretty similar, but with async/await syntax:
async function getStockStatistics(){
//Get symbol from input field
inputSymbol = document.getElementById("inputSymbol").value;
console.log(inputSymbol);
await request();
updateStockTabel();
}

how to send ids of object to backend funtion?

My knowledge of front end it is not so good, and I don't know how to send array of ids to back end which will get all data and will be open it into new page. pls help
there my function:
#has_session_params('tin')
def print_documents(request):
doc_ids = request.POST.getlist('doc_ids[]')
tin = request.session['tin']
params = dict()
template = 'documents/documents_to_print.html'
params['Docs'] = docs
params['pb'] = pb
params['is_pdf'] = request.GET.get('is_pdf', 'false')
params['host'] = request.scheme + "://" + request.META["HTTP_HOST"]
params['url'] = settings.SITE_URL + request.get_full_path()
params['doc_type'] = INVOICE_TYPE
invoice_list = list()
for doc_id in doc_ids:
response = proxy.get_invoice_by_id(invoice_id=doc_id, tin=tin)
if response.status.code != pb.ResponseStatus.OK:
response = proxy.get_invoice_draft_by_id(
invoice_draft_id=doc_id, tin=tin)
invoice_list.append(response.invoice)
params['invoices'] = invoice_list
return render(request, template, params)
I know how to get one object by id, it will be like:
def print_document(request, doc_id):
and something like that, and where url for function will be look like that:
url(r'^print_documents/(?P<doc_id>[a-z\d]{24})/$', invoices.print_documents, name='print_documents')
and new page link will be like that localhost:8000/documents/print_documents/{doc_id}
and this method I can just call like :
print
but now I want to select several documents and send doc_ids, and I know that I can to like method above but I don't want big link. And how I can send array of ids to back end correctly?
now I have something like that:
printAll.on("click", function(){
var invoicesID = [];
$('input.select-inv-check:checked').each(function() {
invoicesID.push($(this).data('docid'));
});
var url = Globals.printAll;
$.post( url, { doc_ids: invoicesID } ).done(function(result) {
console.log("result", result[0].Docs);
if(result.code == 0){
}else{
alert(result.message);
}
});
});
And I know that it doesn't correct! pls help

Categories