Javascript AJAX How to Fetch Data from API by ID - javascript

I'm trying to create a program that allows a user to input a number and fetches the movie data from an API by accessing the id index, so for example if I wanted to access the 3rd ID of the API, it would fetch all the elements from "https://my-json-server.typicode.com/daijonbereola/restful-api-react/movies/3". So far, no movie has been found and am not sure what is wrong with my Javascript. Here it is pasted below:
<form>
<input type="number" id="inputId" placeholder="Enter a number"/>
<input type="button" id="fetchId" value="Fetch Movie" class="btn btn-primary"/>
</form>
<script>
let id = document.getElementById("inputId").value;
let fetchId = document.getElementById("fetchId");
fetchId.addEventListener("click", selectHandler);
function selectHandler() {
// Instantiate an new XHR Object
const xhr = new XMLHttpRequest();
// Open an obejct (GET/POST, PATH,
// ASYN-TRUE/FALSE)
xhr.open("GET",
`https://my-json-server.typicode.com/daijonbereola/restful-api-react/movies/${id}`, true);
// When response is ready
xhr.onload = function () {
if (this.status === 200) {
// Changing string data into JSON Object
obj = JSON.parse(this.responseText);
// Getting the element
let list = document.getElementById("list");
id = obj.id;
console.log(id);
if(id){
str = ""
str +=
`
<div style="padding: 5px 5px;">
<a href=${obj.url}>${obj.title}</a>
<image style="max-width: 60%;"src=${obj.image} alt = "movie poster"/>
</div>
`;
list.innerHTML = str;
} else{
str = ""
str += `<p>Movie not found...Please try again</p>`;
list.innerHTML = str;
}
}
else {
console.log("File not found");
}
}
xhr.send();
}
</script>

Related

How to change part of a string to a different value on API return using JS?

I am using the Chuck Norris joke generator API. I was wondering if it would be possible in this situation to change part of the string returned 'Chuck Norris' to something else. I've tried a few different ideas and I'm really stuck.
E.g instead of 'Chuck Norris built the hospital he was born in.' the API could return 'Dalai Lama built the hospital he was born in.' instead.
document.querySelector('.get-jokes').addEventListener('click', getJokes);
function getJokes(e) {
const number = document.querySelector('input[type="number"]').value;
const xhr = new XMLHttpRequest();
xhr.open('GET', `http://api.icndb.com/jokes/random/${number}`, true);
xhr.onload = function() {
if (this.status === 200) {
const response = JSON.parse(this.responseText);
console.log(response);
let output = '';
if (response.type === 'success') {
response.value.forEach(function(getjoke) {
output += `<li>${getjoke.joke}</li>`;
});
} else {
output += '<li>Something went wrong</li>';
}
document.querySelector('.jokes').innerHTML = output;
}
};
xhr.send();
e.preventDefault();
}
<div class="container">
<h2>Chuck Norris Joke Generator</h2>
<form>
<div>
<label for="number">Number of jokes</label>
<input type="number" id="number">
</div>
<div>
<button class="get-jokes">Get Jokes</button>
</div>
</form>
<ul class="jokes"></ul>
</div>
I believe this could be an answer
function replaceall(thejoke, what, towhat) {
while (thejoke.includes(what) == true) {
thejoke = thejoke.replace(what, towhat);
}
return thejoke
}
thejoke Is the string, And the function takes all of what in thejoke and turns it in to towhat
This Is a program I made using this function.

How to send sentences, not single words, to an API and get them send back

I am working on a project to convert an old Irish dictionary that uses non-standardised spelling. The objective is to send the non-standardised text to an API that will convert it to standardised spelling.
The user should only have to click a button and the text will be sent behind the scenes to the API. The standardised spelling will return in two seconds and be seen on the webpage.
It sounds easy but is surprisingly difficult. The code for the API is here
The instructions for setting it up is
Here is code, both HTML and JavaScript, for running something similar:
window.addEventListener("load", function () {
var form = document.getElementById("IGform");
form.addEventListener("submit", function (event) {
event.preventDefault();
var XHR = new XMLHttpRequest();
XHR.onreadystatechange = function(event) {
if (XHR.readyState == XMLHttpRequest.DONE) {
if (XHR.status == 200) {
processPairs(JSON.parse(event.target.responseText));
}
else {
var div=document.getElementById("output");
div.innerHTML=XHR.status.toString()+': '+XHR.statusText;
}
}
};
XHR.open("POST", "https://cadhan.com/api/intergaelic/3.0");
XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
XHR.setRequestHeader('Accept','application/json');
var payload = '';
var radios = document.getElementsByName('foinse');
for (var i=0; i<radios.length; i++) {
if (radios[i].checked) {
payload = 'foinse='+radios[i].value+'&teacs=';
break;
}
}
payload += encodeURIComponent(document.getElementById('sourcetext').value);
XHR.send(payload);
var div=document.getElementById("output");
div.innerHTML='<em>Translating...</em>'
});
});
function processPairs(arr) {
var div=document.getElementById("output");
var suppress = true;
div.innerHTML='';
for(var i=0; i<arr.length; i++) {
t=arr[i][1];
if (t=="\\n") {
div.innerHTML+='<br/>';
suppress = true;
}
else {
if (suppress==false && !t.match(/^[.,\/;”:!?%})]$/)) {
div.innerHTML+=" ";
}
suppress = (t.match(/^[“\/$(\[#{]$/)!==null);
div.innerHTML+=t;
}
}
}
<form id="IGform">
<textarea rows="10" cols="40" id="sourcetext" name="teacs" wrap="virtual"></textarea>
<br/><br/>
<input type="submit" value="Submit"></input>
<input type="reset" value="Clear"></input>
<br/><br/>
Source language:<br/>
<input type="radio" name="foinse" value="gd" checked>Scottish Gaelic</input><br/>
<input type="radio" name="foinse" value="gv">Manx Gaelic</input><br/>
<input type="radio" name="foinse" value="ga">Pre-Standard Irish</input><br/>
</form>
<hr/>
<div id="output"></div>
What I am trying to create instead of a form is a text that is already formatted in HTML. The user can click a button and the JavaScript will send the text to the API and then the standardised spelling will be provided pretty quickly thereafter.
I hope that it is easy to understand. Any help with this matter would really appreciated.

Use Template Literal as an object

I have an input at the end of my table and I want it to have a different ids for each row. I made something like this:
`<td><input type="number" name="quantity${article.ID}" id="quantity${article.ID}" min="1" max="5"></td>`
This works well, as when I look in the html, it gives me something like: quantity1, quantity2 etc.
The thing is, when i try to call these ids dynamically, it returns null. Here is the full javascript code:
//load JSON file
var articles = ""
var txt = ""
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
articles = xmlhttp.responseText;
txt = JSON.parse(articles);
console.log(txt);
processArticles(txt);
processForm(txt);
}
};
xmlhttp.open("GET","../articles.json",true);
xmlhttp.send();
function processArticles(article) {
var tableStart = `
<h2>Liste des articles</h2>
<form id="formtable">
<table>
<tr>
<th>ID</th>
<th>Article</th>
<th>Prix</th>
<th>Prix-Retour</th>
<th>Quantitée maximale</th>
<th>Projet</th>
<th>Quantitée</th>
</tr>`;
var tableEnd = `
</table>
<input type="submit">
</form>`;
function articlesTemplate(article) {
return `
<tr>
<td>${article.ID}</td>
<td>${article.Article }</td>
<td>${article.Prix}</td>
<td>${article.PrixRetour}</td>
<td>${article.QuantiteeMaximale}</td>
<td>${article.Projet}</td>
<td><input type="number" name="quantity${article.ID}" id="quantity${article.ID}" min="1" max="5"></td>
</tr>
`;
}
let mctxt=txt.filter(value=>
value.Projet=="mc");
document.getElementById("tablemc").innerHTML = `
${tableStart}
${mctxt.map(articlesTemplate).join("")}
${tableEnd}
`;
;
}
function processForm(article) {
var form = document.getElementById('formtable');
var quantity = document.getElementById([`quantity${article.ID}`]);
form.onsubmit = function(e) {
e.preventDefault();
console.log(quantity);
};
}
The quantity variable returns as null when I log it. Any ideas on how I could fix this?

How do I change this Contact Form's Javascript so that IF a key is something else, perform different action?

I have a Contact Form that utilizes Google Scripts. It successfully sends the email and formats it decently to my inbox, but there are 2 problems:
-I need it so that IF var key is equal to 'Action', then do not display it in the email it sends. Because right now, "Action send_message" is getting included in the email and I don't like that.
For this, I have unsuccessfully tried things like:
for (var idx in order) {
var key = order[idx];
//Skip this entry into the email output if it is the Action
if( key === 'Action') {
continue
}
It seems to not react to this code at all.
-I also need it so that if a city is selected, e.g. Alachua, that the email says 'Alachua' instead of 'Florida_Alachua'. But I can't add a NAME to an option since apparently options don't have that property. I also can't do the quick fix of changing the VALUE of the <option> to resolve this step, because of other code I have that conflicts with this route.
Google Scripts Code:
/******************************************************************************
* This tutorial is based on the work of Martin Hawksey twitter.com/mhawksey *
* But has been simplified and cleaned up to make it more beginner friendly *
* All credit still goes to Martin and any issues/complaints/questions to me. *
******************************************************************************/
// if you want to store your email server-side (hidden), uncomment the next line
var TO_ADDRESS = "myemail#email.com";
// spit out all the keys/values from the form in HTML for email
// uses an array of keys if provided or the object to determine field order
function formatMailBody(obj, order) {
var result = "";
if (!order) {
order = Object.keys(obj);
}
// loop over all keys in the ordered form data
for (var idx in order) {
var key = order[idx];
result += "<h4 style='text-transform: capitalize; margin-bottom: 0'>" + key + "</h4><div>" + sanitizeInput(obj[key]) + "</div>";
// for every key, concatenate an `<h4 />`/`<div />` pairing of the key name and its value,
// and append it to the `result` string created at the start.
}
return result; // once the looping is done, `result` will be one long string to put in the email body
}
// sanitize content from the user - trust no one
// ref: https://developers.google.com/apps-script/reference/html/html-output#appendUntrusted(String)
function sanitizeInput(rawInput) {
var placeholder = HtmlService.createHtmlOutput(" ");
placeholder.appendUntrusted(rawInput);
return placeholder.getContent();
}
function doPost(e) {
try {
Logger.log(e); // the Google Script version of console.log see: Class Logger
record_data(e);
// shorter name for form data
var mailData = e.parameters;
// names and order of form elements (if set)
var orderParameter = e.parameters.formDataNameOrder;
var dataOrder;
if (orderParameter) {
dataOrder = JSON.parse(orderParameter);
}
// determine recepient of the email
// if you have your email uncommented above, it uses that `TO_ADDRESS`
// otherwise, it defaults to the email provided by the form's data attribute
var sendEmailTo = (typeof TO_ADDRESS !== "undefined") ? TO_ADDRESS : mailData.formGoogleSendEmail;
// send email if to address is set
if (sendEmailTo) {
MailApp.sendEmail({
to: String(sendEmailTo),
subject: "Contact form submitted",
// replyTo: String(mailData.email), // This is optional and reliant on your form actually collecting a field named `email`
htmlBody: formatMailBody(mailData, dataOrder)
});
}
return ContentService // return json success results
.createTextOutput(
JSON.stringify({"result":"success",
"data": JSON.stringify(e.parameters) }))
.setMimeType(ContentService.MimeType.JSON);
} catch(error) { // if error return this
Logger.log(error);
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": error}))
.setMimeType(ContentService.MimeType.JSON);
}
}
/**
* record_data inserts the data received from the html form submission
* e is the data received from the POST
*/
function record_data(e) {
var lock = LockService.getDocumentLock();
lock.waitLock(30000); // hold off up to 30 sec to avoid concurrent writing
try {
Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
// select the 'responses' sheet by default
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = e.parameters.formGoogleSheetName || "responses";
var sheet = doc.getSheetByName(sheetName);
var oldHeader = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var newHeader = oldHeader.slice();
var fieldsFromForm = getDataColumns(e.parameters);
var row = [new Date()]; // first element in the row should always be a timestamp
// loop through the header columns
for (var i = 1; i < oldHeader.length; i++) { // start at 1 to avoid Timestamp column
var field = oldHeader[i];
var output = getFieldFromData(field, e.parameters);
row.push(output);
// mark as stored by removing from form fields
var formIndex = fieldsFromForm.indexOf(field);
if (formIndex > -1) {
fieldsFromForm.splice(formIndex, 1);
}
}
// set any new fields in our form
for (var i = 0; i < fieldsFromForm.length; i++) {
var field = fieldsFromForm[i];
var output = getFieldFromData(field, e.parameters);
row.push(output);
newHeader.push(field);
}
// more efficient to set values as [][] array than individually
var nextRow = sheet.getLastRow() + 1; // get next row
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// update header row with any new data
if (newHeader.length > oldHeader.length) {
sheet.getRange(1, 1, 1, newHeader.length).setValues([newHeader]);
}
}
catch(error) {
Logger.log(error);
}
finally {
lock.releaseLock();
return;
}
}
function getDataColumns(data) {
return Object.keys(data).filter(function(column) {
return !(column === 'formDataNameOrder' || column === 'formGoogleSheetName' || column === 'formGoogleSendEmail' || column === 'honeypot');
});
}
function getFieldFromData(field, data) {
var values = data[field] || '';
var output = values.join ? values.join(', ') : values;
return output;
}
Contact Form HTML
<section id="contact-form">
<form id="gform"
class="contact-form" method="post"
action="(Google Scripts URL)"
enctype="text/plain">
<p>
<label for="name">Your Name <font face="Arial" color="red">*</font></label>
<input type="text" style="height:35px;" class="heighttext required" name="name" id="name" class="required" title="* Please provide your name">
</p>
<p>
<label>Your Location <font face="Arial" color="red">*</font></label>
<select name="Location" id="column_select" style="height:35px;" class="required" title=" * Please provide your location">
<option selected value="col00">-- State --</option>
<option value="Alabama">Alabama</option>
<option value="California">California</option>
<option value="Florida">Florida</option>
</select>
<select name="City" id="layout_select" style="height:35px;">
<option disabled selected value="Florida">-- City --</option>
<option name="Alachua" value="Florida_Alachua">Alachua</option>
<option name="Alford" value="Florida_Alford">Alford</option>
</select>
</p>
<p>
<input type="submit" value="Send Message" id="submit" class="pp-btn special">
<img src="images/ajax-loader.gif" id="contact-loader" alt="Loading...">
<input type="hidden" name="action" value="send_message">
</p>
</form>
</section><!-- #contact-form -->
Form Handler Javascript
(function() {
function validEmail(email) { // see:
var re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
}
function validateHuman(honeypot) {
if (honeypot) { //if hidden form filled up
console.log("Robot Detected!");
return true;
} else {
console.log("Welcome Human!");
}
}
// get all data in form and return object
function getFormData() {
var form = document.getElementById("gform");
var elements = form.elements;
var fields = Object.keys(elements).filter(function(k) {
return (elements[k].name !== "honeypot");
}).map(function(k) {
if(elements[k].name !== undefined) {
return elements[k].name;
// special case for Edge's html collection
}else if(elements[k].length > 0){
return elements[k].item(0).name;
}
}).filter(function(item, pos, self) {
return self.indexOf(item) == pos && item;
});
var formData = {};
fields.forEach(function(name){
var element = elements[name];
// singular form elements just have one value
formData[name] = element.value;
// when our element has multiple items, get their values
if (element.length) {
var data = [];
for (var i = 0; i < element.length; i++) {
var item = element.item(i);
if (item.checked || item.selected) {
data.push(item.value);
}
}
formData[name] = data.join(', ');
}
});
// add form-specific values into the data
formData.formDataNameOrder = JSON.stringify(fields);
formData.formGoogleSheetName = form.dataset.sheet || "responses"; // default sheet name
formData.formGoogleSendEmail = form.dataset.email || ""; // no email by default
console.log(formData);
return formData;
}
function handleFormSubmit(event) { // handles form submit without any jquery
event.preventDefault(); // we are submitting via xhr below
var data = getFormData(); // get the values submitted in the form
/* OPTION: Remove this comment to enable SPAM prevention, see README.md
if (validateHuman(data.honeypot)) { //if form is filled, form will not be submitted
return false;
}
*/
if( data.email && !validEmail(data.email) ) { // if email is not valid show error
var invalidEmail = document.getElementById("email-invalid");
if (invalidEmail) {
invalidEmail.style.display = "block";
return false;
}
} else {
disableAllButtons(event.target);
var url = event.target.action; //
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
// xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
console.log( xhr.status, xhr.statusText )
console.log(xhr.responseText);
//document.getElementById("gform").style.display = "none"; // hide form
/*
var thankYouMessage = document.getElementById("thankyou_message");
if (thankYouMessage) {
thankYouMessage.style.display = "block";
}
*/
return;
};
// url encode form data for sending as post data
var encoded = Object.keys(data).map(function(k) {
return encodeURIComponent(k) + "=" + encodeURIComponent(data[k])
}).join('&')
xhr.send(encoded);
}
}
function loaded() {
console.log("Contact form submission handler loaded successfully.");
// bind to the submit event of our form
var form = document.getElementById("gform");
form.addEventListener("submit", handleFormSubmit, false);
};
document.addEventListener("DOMContentLoaded", loaded, false);
function disableAllButtons(form) {
var buttons = form.querySelectorAll("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].disabled = true;
}
}
})();
finally, this is the extra code that would break if I simply tried changing the value of option to, e.g., 'Alachua' instead of 'Flordia_Alachua'. https://jsfiddle.net/hmatt843/504dgmqy/19/
Thanks for any and all help.
Try console.log(key) before if( key === 'Action'). I think you'll find that key never equals 'Action', exactly. Looks like you'll need if( key === 'action'), instead.
If you wish to remove part of string value, try the replace method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
It also looks like you're trying to work with elements[k].name when you mean to be working with elements[k].value.
I believe your code should look something like...
function(k) {
if(elements[k].value !== undefined) {
return elements[k].value.replace('Florida_', '');
// special case for Edge's html collection
} else if(elements[k].length > 0){
return elements[k].item(0).value.replace('Florida_', '');
}
}
... or something to that effect.
In the future, you may want to make it easier for folks trying to help you by posting only the portions of code your having trouble with, and breaking your questions into different posts. A lot to sift through up there.
Hope this helped.
The split() method splits a String object into an array of strings by separating the string into substrings, using a specified separator string to determine where to make each split.
Var splitValue = elements[k].item(0).value.split("");
splitValue[1] will give you a string of characters after the delimeter () in this case.

send from first html to java script in another html

I have two html, first sends value to another. I want in second html receive data in javascript. On first html page user would be able to insert localhost:8888 address, address should be send to java script in another html...for now i have default address in java script .. please help.
first html
<form action="second.html" method="GET" >
<input type="text" name="" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
second html
<script>
$(document).ready(function () {
var ws = new WebSocket("ws://localhost:8888/ws");
ws.onopen = function(evt) {
var conn_status = document.getElementById('conn_text');
conn_status.innerHTML = "Status: Connected!"
};
...
got more code
<script>
...
You can get submitted data from URL, because your from has submit method GET:
first html:
<form action="second.html" method="GET" >
<!-- In this way we can get submitted data from get param "host" -->
<input type="text" name="host" />
<input type="submit" value="Submit" />
</form>
second html:
<script>
$(document).ready(function () {
// function to get params from url
function getQueryParams(query) {
query = query || window.location.search;
if (query.length === 0) {
return {};
}
var params = {};
var paramsArr = query.split('&');
for (var i = 0; i < paramsArr.length; i++) {
var p = paramsArr[i].split("=");
params[p[0]] = p[1] || '';
}
return params;
}
// try to get param "host" from url (which submitted from first html)
var queryParams = getQueryParams();
var host = queryParams.host || 'localhost:8888';
var ws = new WebSocket('ws://' + host + '/ws');
ws.onopen = function (evt) {
var conn_status = document.getElementById('conn_text');
conn_status.innerHTML = "Status: Connected!"
};
// more code
}
</script>

Categories