Unable to link backend post api with frontend submit button - javascript

I am trying to make a zomato random restaurant generator, so whenever you put your city it gives a random restaurant in that city. I made api for it and it works perfectly, this is a sample output of the api call
{
"name": "Natural Ice Cream",
"url": "https://www.zomato.com/ncr/natural-ice-cream-rajouri-garden-new-delhi?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
"location": {
"address": "J 2/10, BK Dutt Market, Rajouri Garden, New Delhi",
"locality": "Rajouri Garden",
"city": "New Delhi",
"city_id": 1,
"latitude": "28.6474674597",
"longitude": "77.1195488423",
"zipcode": "",
"country_id": 1,
"locality_verbose": "Rajouri Garden, New Delhi"
},
"price": 1,
"thumbnail": "https://b.zmtcdn.com/data/pictures/8/313368/da7c191473cdc9701aa97a8cbcd51255.jpg?fit=around%7C200%3A200&crop=200%3A200%3B%2A%2C%2A",
"rating": "4.7"
}
the backend linking frontend to backend looks like this
searchForm.addEventListener('submit', async e => {
e.preventDefault();
resultArea.innerHTML = '';
const query = e.target.querySelector('#restaurant-name').value;
if (query === '') {
return
}
e.target.querySelector('#restaurant-name').value = '';
const res = await fetch(`${hostname}/locations/${query}`, {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
method: 'POST',
})
const json = await res.json();
populateData(json);
});
function populateData(results) {
results.forEach(result => {
const newResult = rTemp.content.cloneNode(true);
newResult.querySelector('.result-title').innerText = result.name;
newResult.querySelector('.result-neighborhood').innerText = result.location.locality;
newResult.querySelector('.result-address').innerText = result.location.address;
newResult.querySelector('.result-price').innerText = '$'.repeat(result.price);
newResult.querySelector('.result-thumbnail').src = result.thumbnail;
newResult.querySelector('.result-website').href = result.url;
resultArea.appendChild(newResult);
});
}
here rTemp is querySelector('template') and resultArea is querySelector('#restaurant-results') and hostname is this.location.origin
And lastly this is the frontend
<body>
<div class="wrapper">
<main>
<h1>Restaurant <span>Random</span></h1>
<form action="">
<div class="form-wrapper">
<label for="restaurant-name">Search</label>
<input name="restaurant-name" type="text" id="restaurant-name" placeholder="City Name">
</div>
<input type="submit">
</form>
</main>
<hr>
<section id="restaurant-results">
</section>
</div>
<template>
<div class="result-card">
<div class="result-header">
<h2 class="result-title">${title}</h2>
<h3 class="result-location result-neighborhood">${neighborhood}</h3>
<h3 class="result-location result-address">${address}</h3>
<p class="result-price">${price}</p>
</div>
<div class="result-body">
<img src="" alt="restaurant-photo" class="result-thumbnail">
</div>
<div class="result-footer">
<button class="result-footer-button">Call</button>
<button class="result-footer-button">Visit Website</button>
<button class="result-footer-button">Make Reservation</button>
</div>
</div>
</template>
<script src="index.js"></script>
</body>
When I run this I get the following error
POST http://127.0.0.1:5500/locations/delhincr 405 (Method Not Allowed)
(anonymous) # index.js:16
index.js:16 is
const res = await fetch(`${hostname}/locations/${query}`, {
and
Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at HTMLFormElement. (index.js:22) which is
const json = await res.json();
I am unable to locate the error. How do I solve these?

Related

how to add text and values to array

{
"user": "someuser",
"message": "need a help"
},
{
"user": "bot",
"message": "can i help you?"
},
{
"user": "someuser",
"message": "another question"
}
I need to read additional paragraphs on the page and add them to my json - object, for sending to the server. The positions can be around 10-20!
.edited-phrase and .phrase-return is what is already on the page in .client-mess and .bot-mess I fill in the data from json. Sending ajax is not a problem, the problem is to form correct data(
The final version should look like this:
{
"user": "someuser",
"message": "need a help"
"edited": "hello",
"return": "return on step_1",
},
{
"user": "bot",
"message": "can i help you?"
}
{
"user": "someuser",
"message": "another question"
"edited": "forget",
"return": "return on step_3",
},
Thank you in advance!
<div class="message-row">
<div class="client-say">
<p class="client-mess" data-user="someuser">need a help</p>
<div class="return-container">
<p class="edited-phrase">hello</p>
<p class="phrase-return">return on step_1</p>
</div>
</div>
</div>
<div class="message-row">
<div class="bot-say">
<p class="bot-mess" data-user="bot">can i help you?</p>
</div>
</div>
<div class="message-row">
<div class="client-mess data-user="someuser"">
<p class="phrase-return">another question</p>
<div class="return-container">
<p class="edited-phrase">forget</p>
<p class="phrase-return">return on step_3</p>
</div>
</div>
</div>
<div class="">
<a id="sendJson" href="#" class="" >send Json</a>
</div>
</div>
$('#sendJson').on('click', function() {
var messagesArray = [];
$dialogMessages = {};
$(".container .message-row")
.each(function () {
$dialogMessages = {
user:$(this).data('user'),
/* message:$(this).text(),
phraseEdited: ,
phraseReturn: , */
}
messagesArray.push($dialogMessages);
});
})
In browser environment, you can use querySelectorAll method:
const paragraphsWithClassReturn = document.querySelectorAll('p.return');
See querySelectorAll on MDN.
After this, you can turn the result into an array and loop through it using available array methods:
Array.from(paragraphsWithClassReturn).forEach(paragraph => {
// your code doing something with every found paragraph
})
In jQuery, you select elements having return class using
const $paragraphsWithClassReturn = $('p.return')
...and then loop through them with .each method:
$paragraphsWithClassReturn.each($paragraph => {
// your code doing something with every found paragraph
});

Function that is set within the same script is defined and then undefined

Browser Console Error
Uncaught ReferenceError: getNewCars is not defined at HTMLDivElement.onclick
Code Explained
I'm building a car selector form. How it works is there's categories (known as seasons) that can be clicked on to bring up a list of specific cars that pertain to that category (season).
Html
<div class="chooseCar">
<div class="chooseCarTabs">
</div>
<div class="chooseCarWrapper">
<div id="chooseCarSelection">
</div>
</div>
</div>
<script src="/public/theme/scripts/car-selection.js"></script>
car-selection.js
alert('new car-selection js')
let cars;
let seasons = [
{
"name": "Seasonal Cars",
"path": "seasonal.json"
},
{
"name": "Modern Cars",
"path": "modern.json"
},
{
"name": "Classic Cars",
"path": "classic.json"
},
{
"name": "Flag Cars",
"path": "flags.json"
}
];
let seasonTab = "Seasonal Cars";
const chooseCarBody = document.getElementById('chooseCarSelection');
const seasonsTabs = document.getElementsByClassName('chooseCarTabs')[0];
function loadCars(){
chooseCarBody.innerHTML = '';
cars.forEach(car => {
chooseCarBody.innerHTML += `
<div class="singleCar">
<div class="singleCarInner">
<img src="/public/images/avatars/${car.filename}" alt="${car.name}">
</div>
</div>
`
})
}
//Ajax Request
async function setSeasons() {
seasonsTabs.innerHTML = ''
await seasons.forEach(season => {
seasonsTabs.innerHTML += `
<div ${seasonTab == season.name ? 'class="activeSeasonTab"' : ''} onclick="getNewCars('${season.name}', '${season.path}' )">
${season.name}
</div>
`
});
}
//Will be replaced with AJAX Request
async function getNewCars(seasonName, season = seasons[0].path){
cars = null;
await fetch(`/public/data/cars/${season}`)
.then(response => response.json())
.then(data => {
console.log(data)
seasonTab = seasonName;
cars = data; console.log(cars)
})
.catch(error => console.log(error));
await loadCars()
}
async function initData(){
await setSeasons();
await getNewCars(seasons[0].name);
}
initData();
Extra code explanation
let cars; and let seasons work as a state of sorts. When a seasons tab is clicked on an ajax request is sent to get fill the cars state with cars for the category which is then looped through and populated on the page.
My Problem
When I reload the page the cars and category (season) tabs appear on the page just fine including the getNewCars(). But when I go to click on:
<div
${seasonTab == season.name ? 'class="activeSeasonTab"' : ''}
onclick="getNewCars('${season.name}', '${season.path}' )"
>
${season.name}
</div>
I get this error:
Uncaught ReferenceError: getNewCars is not defined at HTMLDivElement.onclick
Note, inline scripts I don't seem to get this error:
<div class="chooseCar">
<div class="chooseCarTabs">
</div>
<div class="chooseCarWrapper">
<div id="chooseCarSelection">
</div>
</div>
</div>
<script> /* All scripts in here*/</script>
How do I fix this and what's going wrong with my code that when import from another js file this happens?

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.

call rest api and display result as searched for

I am calling a REST API from this HTML form
<form action="#">
<h1>Enter your zip code</h1>
<div class="form-group">
<label for="zip">Zip Code</label>
<input type="text" id="zip">
</div>
<div class="button-holder">
<button class="btn btn-primary" onclick="callREST()">Next</button>
</div>
</form>
My API structure looks like this
{
"Agents":
{
"#ZipCode": "33176",
"Agent": [
{
"AgencyID": "21",
"Name": "Anakarina Callejas",
"Phone": "305-515-5613",
"CityName": "KENDALL",
"Address": "10471 N Kendall Dr. #101. Miami, FL 33176",
"Reviews-Rating": "5",
"Reviews-Count": "74",
"image": "/images/agents/21.png"
},
{
"AgencyID": "116",
"Name": "Tamara Mourino",
"Phone": "305-256-0616",
"CityName": "PINECREST",
"Address": "12745 South Dixie Highway. #101. Pinecrest, FL 33156",
"Reviews-Rating": "5",
"Reviews-Count": "70",
"image": "/images/agents/116.png"
}]
}
}
and this is how i am calling the API
function callREST() {
// Create a request variable and assign a new XMLHttpRequest object to it.
var request = new XMLHttpRequest();
// Open a new connection, using the GET request on the URL endpoint
request.open('GET', 'URL to the API', true);
request.onload = function () {
// Begin accessing JSON data here
var responseData = JSON.parse(this.response);
var data = responseData.Agents.Agent;
if (request.status >= 200 && request.status < 400) {
data.forEach(agent => {
// Log each agent's title
console.log(agent.Name);
});
} else {
console.log('error');
}
}
// Send request
request.send();
}
I get all the data but what i need is only the data that matches the ZIP Code entered in the input field
You can get #ZipCode value from Agents object and compare with the input value.
var responseData =JSON.parse(jsonResponse);
var zipCode= responseData.Agents['#ZipCode'];
Here is the working snippet that display the alert if input value is matched with sample data' zipCode value.
var jsonResponse='{"Agents":{"#ZipCode": "33176","Agent": [{"AgencyID": "21","Name": "Anakarina Callejas","Phone": "305-515-5613","CityName": "KENDALL","Address": "10471 N Kendall Dr. #101. Miami, FL 33176","Reviews-Rating": "5","Reviews-Count": "74","image": "/images/agents/21.png"},{"AgencyID": "116","Name": "Tamara Mourino","Phone": "305-256-0616","CityName": "PINECREST","Address": "12745 South Dixie Highway. #101. Pinecrest, FL 33156","Reviews-Rating": "5","Reviews-Count": "70","image": "/images/agents/116.png"}]}}';
function callREST() {
event.preventDefault();//for demo to prevent form submit.
var inputZip=document.getElementById("zip").value;
var responseData =JSON.parse(jsonResponse);
var zipCode= responseData.Agents['#ZipCode'];
//console.log(inputZip,zipCode);
if(zipCode==inputZip){
alert("ZipCode matched.");
}else{
alert("ZipCode not matched.");
}
}
<form action="#">
<h1>Enter your zip code</h1>
<div class="form-group">
<label for="zip">Zip Code</label>
<input type="text" id="zip">
</div>
<div class="button-holder">
<button class="btn btn-primary" onclick="callREST();">Next</button>
</div>
</form>
Note: From comments it is still confusing that how your response object can have multiple zipCode.
#Comment- Look at your code responseData.Agents.Agent responseData is an object, Agents is an object, how there can be multiple Agents objects in an object. Or even how can be multiple ZipCode prpertirs in Agents object

Categories

Resources