How can I put my API get's return value onto an html page?
If I do:
const url = "https://alloysystems.freshdesk.com/api/v2/tickets";
fetch(url, {
method: "GET",
withCredentials: true,
headers: {
// needed to base64 encode my key with ":x" at the end of the api key then I used that for the authorization header.
"authorization": "Basic ILLNEVERGIVEYOUMYKEYKEYLOL"
}
})
.then(resp => resp.json())
.then(data => console.log(data))
I get a bunch of objects, (I think) in the console log:
However if I try to add the data to html tag so I can see it on a webpage, I either get a failure or I get [Object],[Object]
Attempted code:
Html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Today's Date</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script src="js/script.js"></script>
</body>
</html>
Javascript:
let d = new Date();
const url = "https://alloysystems.freshdesk.com/api/v2/tickets";
fetch(url, {
method: "GET",
withCredentials: true,
headers: {
// needed to base64 encode my key with ":x" at the end of the api key then I used that for the authorization header.
"authorization": "Basic ILLNEVERGIVEYOUMYKEYKEYLOL"
}
})
.then(resp => resp.json())
.then(data => document.body.innerHTML = "<h1>" + data + "</h1>")
Result:
data is an object so if you want to show everything of it between the h1 tag you need to stringify it first like so :
.then(data => document.body.innerHTML = "<h1>" + JSON.stringify(data) + "</h1>")
If you just want to show the type for example you need to specify that part like so:
.then(data => document.body.innerHTML = "<h1>" + data.type + "</h1>")
You need to convert it from an Object to JSON using
JSON.stringify(value, replacer, space)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
If you want to show it formatted (multiline and indented) on the html page, put in inside a <pre> tag.
See example below in the snippet
fetch(
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&per_page=2&page=1`
)
.then((r) => r.json())
.then((d) => {
const pre = document.createElement('pre');
pre.innerText = JSON.stringify(d, null, `\t`)
document.querySelector('body').appendChild(pre);
});
body,
pre {
color: white;
background: #0080ff;
font-family: Calibri
}
Related
I am getting undefined when I type the author name in the text box and press the button to display the quote. It seems like my button and textbox are not linked together. How can I fix this?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Quotes</title>
</head>
<body>
<label for="getQuotes">Find Quotes (Type Author Name)</label><br>
<input type = "text" id="getQuotes" name="getQuotes" placeholder="Search" style="margin:10px" size="50"/><br />
<button id="FetchQuotes" onclick="getQuote()" style="margin:10px">Fetch Quotes</button>
<p id="quotes"></p>
<p id="author"></p>
<script>
async function getQuote() {
//const author = Boolean(false);
let url = 'https://jaw1042-motivate.azurewebsites.net/quote';
let author = document.getElementById('getQuotes').value;
if(author) {
url = 'https://jaw1042-motivate.azurewebsites.net/quote?author= ';
console.log(url + author);
} else {
console.log(url);
}
fetch(url)
.then(async (response) => {
if (response.ok) {
console.log("Response code: " + response.status);
} else if (response.status === 400) {
console.log("Unable to find any quotes by specified author: " + response.status);
} else {
console.log("No quotes have been loaded: " + response.status);
}
const val = await response.json();
console.log(val);
}).then(data => {
document.getElementById('quotes').value = data;
document.getElementById('author').value = data;
console.log(data);
alert(data);
});
}
</script>
</body>
</html>
your then functions are not correct
in the direct result of the fetchAPI you can receive data and to use it you need to run .json() or .text() on it, you can't simply use that result or return it's value ( plus when you use return statement all your next codes will be unreachable)
after that you should not assign something to your data variable because it just has new Data fetched from backend, by assigning new value to data you're about to ruin new data
here is how your js should look
function getQuote() {
fetch("https://krv1022-motivate.azurewebsites.net/quote")
.then( res => res.text() )
.then( data => {
document.querySelector(".quote").value = data;
}
);
}
I also provided a fiddle for it but it can't receive data because either your URL is not correct or there is CORS issues
==============================================
one thing that I just noticed, you are receiving Author's name from end user but you are not about to send it to backend!
so perhaps this code is more complete, I assume that you want to send data using GET method and backend wants the name of author to be named getQuotes
I'd like to start by mentioning that I'm using vanilla Javascript and PHP, no jquery. The code that I have posted below is just a fragment. I have not included the PHP file or other code in javascript.
Now, the problem I am having is that no other code besides the form data post runs whenever I click my save button and activate the event. I have a console log at the beginning and end of the event to test if other code runs, and it never does. The form data, in this case a picture, gets posted to the PHP rest API file and stored in a folder as it should, but I do not receive a response in JSON from the PHP file that it is posted to, and my biggest problem is that no other code besides the post request runs in the event of the javascript code. Neither of the console.logs (test 1 and test 2) will appear.
When I test the post request with any other type of data, for instance, JSON, everything works perfectly. All of the code in the event runs, and I can receive responses in JSON from the same PHP file that the request was made to. There's something about posting form data that creates this bug. I hope that I have explained this clearly enough. Thank you for any assistance.
save_bg_btn.addEventListener('click', save_background_picture);
async function save_background_picture(){
console.log("test 1");
const formData = new FormData();
const save_files_background_pic = file_bg_pic.files[0];
const url = 'http://localhost/test/background-cover.php';
formData.append("file_bg_pic", save_files_background_pic);
await post_formdata_request(url, formData)
.then(data =>{
console.log(data);
})
.catch(err => console.log(err));
console.log(test 2);
}
function post_formdata_request(url, formData){
return new Promise((resolve, reject) => {
fetch(url, {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => resolve(data))
.catch(err => reject(err));
});
}
Assuming this button is in a form, I think you need to add preventDefault() for the click event otherwise the form will submit and refresh the page. Also, fix the second console.log because that was breaking my tests until I noticed it as well.
async function save_background_picture(e){
e.preventDefault();
// ...rest of the code
console.log("test 2"); // <--- needed quotes
}
html file: test-fetch.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form id="myForm">
<input type="file" id="inpFile">
</form>
</body>
<script>
const inpFile = document.getElementById('inpFile');
const myForm = document.getElementById('myForm');
myForm.addEventListener('change', inpFunction);
async function inpFunction(e){
e.preventDefault();
const endpoint = "http://localhost/php-practice/test-fetch.php";
const formData = new FormData();
formData.append('inpFile', inpFile.files[0]);
fetch(endpoint, {
method: 'post',
body: formData
})
.catch(err => console.log(err));
}
</script>
</html>
And this is the php file: test-fetch.php
<?php
$file = $_FILES['inpFile'];
$fileName = $_FILES['inpFile']['name'];
$fileTmpName = $_FILES['inpFile']['tmp_name'];
$fileSize = $_FILES['inpFile']['size'];
$fileError = $_FILES['inpFile']['error'];
$fileType = $_FILES['inpFile']['type'];
$fileExt = explode('.', $fileName);
$fileActualExt = strtolower(end($fileExt));
$allowed = array('jpg', 'jpeg', 'png', 'pdf');
if(in_array($fileActualExt, $allowed)){
if($fileError === 0){
if($fileSize < 2000000){
$fileNameNew = uniqid('', true).".".$fileActualExt;
$fileDestination = 'images/'.$fileNameNew;
move_uploaded_file($fileTmpName, $fileDestination);
}else{
echo "Your file is too large!";
}
}else{
echo "There was an error uploading your file!";
}
}else{
echo "You cannot upload files of this type!";
}
echo 'Success';
?>
Now, if you add any other code, such as a console log inside the function "inpFunction" it will not run. The only code that will run will be the fetch posting the form data to the php file. This problem is really baffling me.
edit: the php file requires a folder called "images" as that is the path destination of any pictures being posted.
I'm trying to get a piece of text that is inside a <div class> of a especific URL and return only the content inside the <a title>. Like "<div class="test"><a title="Hello World"></a></div>" and return Hello World.
But I don't know what should do to return pieces of the text, it's returning whole html.
const fetch = require("node-fetch");
fetch('https://www.google.com/')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(template)
console.log("DONE");
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
fetch('https://www.myear.sg/test.php')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(find_id_details (template))
document.getElementById("abc").innerHTML = find_id_details (template)
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
function find_id_details (input){
var part1 = input.split('<div id="abcd">')[1];
var part2 = part1.split('"></a>')[0];
var part3 = part2.split('<a title="').pop()
return part3
}
<div id="abc"> after the processing , you will get the answer </div>
You can check this answer :
your issue was : "But I don't know what should do to return pieces of the text, it's returning whole html."
lets assunme your html file is :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="abcd"> <a title="Hello World"></a></div>
<div > test 2 </div>
<div > test 3 </div>
</body>
</html>
now you will get the whole html as your response . and you want to parse the HTMl text and want to get the tag title "Hello World":
I make a custom function to parse the input HTML. now I have no idea about your HTML file.
please check the find_id_details() function .
in your code , at the place of console.log(template) , use console.log(find_id_details (template))
fetch('https://example.com/something')
.then(function (response) {
switch (response.status) {
// status "OK"
case 200:
return response.text();
// status "Not Found"
case 404:
throw response;
}
})
.then(function (template) {
console.log(find_id_details (template))
})
.catch(function (response) {
// "Not Found"
console.log(response.statusText);
});
function find_id_details (input){
var part1 = input.split('<div id="abcd">')[1];
var part2 = part1.split('"></a>')[0];
var part3 = part2.split('<a title="').pop()
return part3
}
This should do it:
fetch('https://github.com/')
.then(res => res.text())
.then(body => console.log(body));
Taken from node-fetch documentation https://www.npmjs.com/package/node-fetch
Or if you want to specifically get the title tag, you may use:
var titleTag = body.split('<title>')[1].split('</title>')[0];
if you want to manipulate string HTML, you have first convert it to HTML object (or parse the string). You can do it this way:
var htmlString = '<div class="test"><a title="Hello World"></a></div>';
var temp = document.createElement('div');
temp.innerHTML = htmlString;
var htmlObject = temp.firstChild;
console.log(htmlObject.getElementsByTagName("a")[0].getAttribute("title"))
//Get attribute from all elements by tag
var text = '<div class="test"><a title="Hello World"><a title="Hello Street"></a></a><a title="Hello City"></a></div>';
function getAttributeFromAllElementsByTag(htmlString, tag, attribute){
var tempArray = [];
var temp = document.createElement('div');
temp.innerHTML = htmlString;
var htmlObject = temp.firstChild;
var arrayOfElements = htmlObject.getElementsByTagName(tag);
for(var i = 0;i < arrayOfElements.length;i++){
tempArray.push(arrayOfElements[i].getAttribute(attribute))
}
return tempArray
}
console.log(getAttributeFromAllElementsByTag(text, "a", "title"))
I send an html file to client with res.write() method. I also want to send an object attached to this html.
I tried to stringify that object and write it like I wrote the html file, but when I do that, my stringified json object remains outside of the html. I need that json object to be inside of the html, so I can parse it with the client side js file.
how should I fix that?
I tried to send it as a Json object. but I couldnt get it through the html.
app.get('/uniform', (req,res) => {
fs.readFile('uniformflowindex.html', function(err, data) {
var channelobj = JSON.stringify(channel);
res.write(data);
res.write("<div id='objectstring'>" + channelobj + "</div>");
res.end('');
});
});
it gives the output:
<html>
...
my html file
...
</html>
<div id='objectstring'>{"_events":{},"_eventsCount":0,"Discharge":20,"FlowDepth":5.......}</div>
I just want this div to be in html file..
You could have a wildcard in your html code and then replace the wildcard with your div content.
For example:
<html>
...
my html file
...
[[wildcard]]
</html>
and then use:
app.get('/uniform', (req,res) => {
fs.readFile('uniformflowindex.html', function(err, data) {
var channelobj = JSON.stringify(channel);
res.write(data.replace('[[wildcard]]', "<div id='objectstring'>" + channelobj + "</div>"));
res.end();
})
});
Alternatively may not add a wildcard in your html and just replace one of your closing tags such as <\body> or <\html> with your content + the closing tag itself...
app.get('/uniform', (req,res) => {
fs.readFile('uniformflowindex.html', function(err, data) {
var channelobj = JSON.stringify(channel);
res.write(data.replace('</body>', "<div id='objectstring'>" + channelobj + "</div></body>"));
res.end();
})
});
HTML file:
<html>
...
{ content }
...
</html>
your code:
app.get('/uniform', (req,res) => {
fs.readFile('uniformflowindex.html', function(err, data) {
var channelobj = JSON.stringify(channel);
data = data.replace('{ content }', "<div id='objectstring'>" + channelobj + "</div>");
res.end(data);
})
});
Per Pushbullet API doc I need: Header as: 'Access-Token: o.I'veLearnedNotToPost' 'Content-Type": "application/json' Url is https://api.pushbullet.com/v2/users/me
Problem with my code (don't laugh too hard) is that it only returns "Retrieving information for o.I'veLearnedNotToPost"
Front end code needs to take token from user input text element and put it in backend code (getuser.jsw) to fetch User Info. But the issue is that it's not - nothing except the placeholder text appears in the textbox element (id #result)
Side note: $w is Wix's write to element
// FRONT END CODE
import {getUserInfo} from 'backend/getuser';
export function button1_click(event, $w) {
console.log("Retrieving information for " + $w("#sendToken").value);
getUserInfo($w("#sendToken").value)
.then(usInfo => {
($w("#result").text)
});
}
//BACKEND CODE
import {fetch} from 'wix-fetch';
export function getUserInfo(token) {
let atoken = token;
let url = "https://api.pushbullet.com/v2/users/me";
console.log("Retrieving information for " + atoken);
return fetch("https://api.pushbullet.comm/v2/users/me", {
headers: {
"Access-Token": atoken,
"Content-Type": "application/json"
}
.then(response => response.json())
})}
Thanks in advance for your help!
Greatly appreciated!
-Malc
your Access-Token value is double quoted, try without.