Everyday my teacher looks across the internet to find random facts for us then she writes on the board and we get to see it each day we go in her class. I'm trying to make a super simple website that once a button is clicked an alert at the top of the page appears. Whenever the fact I cant figure out how to make the console go to the alert. I've looked at a different other Stack question but i didn't really understand it. Here is my complete code. I'm sorry i just started javascript and literally couldn't be more new to it. Thanks in advance!
const express = require("express");
const app = express();
app.use(express.static("public"));
app.get("/", (request, response) => {
response.sendFile(__dirname + "/facts.html");
});
const listener = app.listen(process.env.PORT, () => {
console.log("Your app is listening on port " + listener.address().port);
});
var fact = require('random-fact');
fact();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Generate Random Facts</title>
</head>
<body>
<h1>Fact Generator</h1>
<br><br><br><br>
<script>
function test() {
alert('fact');
}
</script>
<input type="button" onclick="test()" value="Generate Random Fact!">
</body>
</html>
I'm sorry if I'm not understanding your code properly but from my understanding the first code block, the NodeJS is sending a file on the root url. That root file is what you want to alert this "random fact"
However, the random fact data is stored in var fact = require("random-fact")
NodeJS is a JavaScript runtime environment. Meaning a place to execute JavaScript code, OUTSIDE the browser and in the server. NodeJS isn't like vanilla JS where you have access to the BOM and DOM.
However, with express you can set up what's called an endpoint. That endpoint will send the data on each request to each route which you can set up on the front end.
First off, I'm assuming the fact() function returns some data. We'll set up an endpoint:
app.get('/random-facts', (req, res) => res.send(fact()));
whenever we send a get request to /random-facts it'll execute the function and hopefully get what you want
On the frontend we need to do what's called an AJAX request. Where you send a request to the API. Like you do in your browser when you type www.google.com you send a get request. AJAX request can get more sophisticated with just GET requests but that's for something else.
We'll do that with JS using the fetch API
On your html you can do
<script>
fetch('http://localhost:3000/random-facts')
.then(response => response.json())
.then(data => alert(data));
</script>
This is probably a bit more advanced than what you know but I hope this helps
Like someone else said, the JavaScript you have up there is server side NodeJS.
Instead, just use your HTML and statically host it on GitHub or something.
Here is an example of a random fact from a list of facts:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Generate Random Facts</title>
</head>
<body>
<h1>Fact Generator</h1>
<p id="fact"> </p>
<script>
// populate with multiple facts
var facts = ["fact one", "fact two", "fact three", "fact four"];
function alertFact() {
const fact = returnFact()
document.getElementById('fact').innerText = fact
alert(fact);
}
function returnFact() {
var fact = facts[Math.floor(Math.random() * facts.length)];
return fact;
}
</script>
<input type="button" onclick="alertFact()" value="Generate Random Fact!" />
</body>
</html>
or you can view it here: https://jsfiddle.net/utdoLbj2/
Related
I need to make a form with 2 input fields. When you press submit it should take you to a new page and display the input data.
This is my html code
<!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>Film survey</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<form id="form" action="./Success.html">
<h1>Movie survey</h1>
<p>Thank you for participating in the film festival!</p>
<p>Please fill out this short survey so we can record your feedback</p>
<div>
<label for="film">What film did you watch?</label>
</div>
<div>
<input type="text" id="film" name="film" required />
</div>
<div>
<label for="rating"
>How would you rate the film? (1 - very bad, 5 - very good)
</label>
</div>
<input type="text" id="rating" name="rating" required />
<div><button class="submit">Submit</button></div>
</form>
<script src="script.js"></script>
</body>
</html>
This is my js code
const formEl = document.querySelector("#form");
formEl.addEventListener("submit", (event) => {
event.preventDefault();
const formData = new FormData(formEl);
fetch("https://reqres.in/api/form", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
film: formData.get("film"),
rating: formData.get("rating"),
}),
})
.then((response) => {
window.location.href = "./Success.html";
})
.catch((error) => {
console.error(error);
});
});
I have a second html page called Success.html which I want to display tha data given in the form. I need to make a mock API so I tried using reqres.
This is my Success.html page
<!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>Success</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Thank you for your feedback!</h1>
<p>You watched: <span id="film"></span></p>
<p>You rated it: <span id="rating"></span></p>
<script>
const formData = JSON.parse(request.body);
const filmEl = document.querySelector("#film");
const ratingEl = document.querySelector("#rating");
filmEl.textContent = formData.film;
ratingEl.textContent = formData.rating;
</script>
</body>
</html>
I thought this would work but I get this error after pressing submit:
`` Success.html:16 Uncaught ReferenceError: request is not defined
at Success.html:16:35
The line const formData = JSON.parse(request.body); in your success.html is trying to reference a variable named request, which isn't defined in the scope of the <script> tag that it's contained in - that's why you're getting the ReferenceError: request is not defined error.
This other Stackoverflow question seems similar to yours - I have linked you to an answer that I think would be helpful. In short, you could pull the values you care about out of your response, then pass them via query parameters to be displayed in your success.html.
Along those same lines, it might make sense for your mock API to respond with a 302 status code and location header including film and rating query parameters that points to your success page.
You can pass along data between web pages in several ways, using JSON data { foo: 'bar' } as an example:
1. Use URL parameter:
Stringify and URL encode your JSON response (full or needed data only), and pass along via a URL parameter
Example: 'data=' + encodeURIComponent(JSON.stringify(data)), resulting in data=%7B%20foo%3A%20'bar'%20%7D
Keep in mind that there is a limit to URL length, varying from 2k to 64k depending on browser
2. Use browser local storage:
The quota is browser specific, in range of 5-10MB, e.g. much larger than URL length
To set in the form page: localStorage.setItem('myFormData', JSON.stringify(data));
To read in success page: let data = JSON.parse(localStorage.getItem('myFormData'); (you likely want to add some error handling)
3. Temporarily POST data
You post the JSON data back to the server to /success
Your success page is delivered dynamically via a server side script that receives the data via a POST, and regurgitates it as JSON or in any other preferred format
Extra work, so not recommended
Having listed that, why not show the content in the form page itself? You can easily update the DOM using native JavaScript or jQuery.
I have a very simple HTML page that connects the page to my Twilio backend:
<!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>
<script src="https://cdn.jsdelivr.net/npm/#twilio/voice-sdk#2.0.1/dist/twilio.min.js"></script>
<script>
connection = null;
call = async () => {
const response = await fetch(
"https://my.token.endpoint/token"
);
const data = await response.json();
const device = new Twilio.Device(data.token);
connection = await device.connect();
connection.on(
"error",
(err) =>
(document.getElementById("error-display").innerHTML = err.message)
);
};
stop = () => {
connection?.disconnect();
connection = null;
};
</script>
</head>
<body>
<button onclick="call()">call</button>
<button onclick="stop()">stop</button>
<p id="error-display"></p>
</body>
</html>
When I open the HTML page from my Windows 10 machine using Chrome 102.0.5005.115, clicking the call button successfully connects to my Twilio backend.
However when I open the HTML page from my Android 12 mobile device using Chrome 102.0.5005.125, clicking the call button triggered the following error:
AcquisitionFailedError (31402): The browser and end-user allowed permissions, however getting the media failed. Usually this is due to bad constraints, but can sometimes fail due to browser, OS or hardware issues.
I was getting this issue beforehand when trying to register the device before setting the current devices. However, since you're only seeing this on mobile, my guess is it's a permissions issue preventing the audio devices to be set. On your phone, can you try removing all permissions for your browser? Then in the code, print out the devices available input and output devices by console logging these:
device.audio.availableInputDevices
device.audio.availableOutputDevices
After refreshing the page, your phone should prompt you to allow audio permissions. If not, may need to take a gander through your settings.
I'm running website on the local server at (http://127.0.0.1:8080).
I have a file named track located at api/track where api is simply a folder.
I have a file name main.js located at js/main.js.
Finally, I have my index.html file located at the same level with /api and /js.
I would like to make a network call to this endpoint (api/track) each time a page index.html loads.
Also, I'd like to include a timestamp ts (in milliseconds since EPOCH). An Example of the url would be /api/track?ts=1594280202864. I don't need to use the results of this call.
Here is what I did, but I'm not sure it's doing what I want especially the network call part. Can somebody help, please? Thanks
const update = () => {
var dt = new Date();
document.getElementById("date").innerHTML = dt;
//date in millisecodn since EPOCH
var dtInMilSec = dt.getTime();
fetch('/api/track/dtMilSec')
.then(response => response.json())
.then(data => {
console.log(data)
});
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The Date</title>
<link href="style/main.css" rel="stylesheet" />
</head>
<body onload="update()">
<h1>What's today's date?</h1>
<p>Today is: <span id="date"></span></p>
<script src="js/main.js"></script>
</body>
https://stackoverflow.com/a/25984032/14649968
Maybe take a look at this answer on a related thread, and call your update() function from within the event listener for DOMContentLoaded within the main.js script, rather calling it from the onload attr in the html itself?
document.addEventListener('DOMContentLoaded', () => update(), false);
Seems like you want your fetch URL to be something like
fetch('/api/track?ts=' + dtInMilSec)
I'm just learning Javascript/API call & I'm having trouble with fetch. When I call the fetch function from myFunction it doesn't do anything (that I can see), but if I take it out of myFunction it will display the error message that I expect.
I've tried to Google this but I haven't found anything that has helped me. I've added the console.log statements to make sure that the function is being called, and it is.
I've tried taking the fetch statement out of the function, and instead just putting it as a script in the html file. It works fine then. However I want to call it using the function name of a function that's in a javascript file & I'd like to understand why it's not working correctly right now. I think it has something to do with fetch not returning before the function exits, but I'm not sure.
javascript function:
function myFunction(){
fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
.then(response => response.text())
.then(data => {
//document.write(data)
console.log(data)
});
//make sure the function was called
console.log("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}
html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ghibli App</title>
<link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div id="root"></div>
<form>
<select id="carrier">
<option value="carrier">Carrier</option>
<option value="icloud">iCloud</option>
</select>
<button onClick="myFunction('carrier');">Submit</button>"
</form>
<script src="scripts.js"></script>
</body>
</html>
I'm expecting to get a page to come up that says "Error S01: Service ID is wrong!" however the page isn't changing at all when I call the code from myFunction().
Why you don't see anything:
The problem isn't that you're calling fetch from within a function, but that you're calling that function within the onclick of a button in a form.
When you place a <button> element inside of a <form> element, its default behavior is to submit the form (posting the results to a different web page and loading that new page in the browser). Since your form doesn't have an action attribute, it will just reload the current page. This reloading of the current page is causing you to not see any results.
Fixing the first issue:
To prevent the form from returning, you need to call preventDefault() on the event passed to your function:
function myFunction(event){
event.preventDefault();
fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
.then(response => response.text())
.then(data => {
//document.write(data)
console.log(data)
});
//make sure the function was called
console.log("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}
The second issue
However because of the way you're calling this function (passing it to the onclick method of an HTML element) you don't have access to that event. To rectify this, you should use the addEventListener method like so:
document.getElementsByTagName("button")[0].addEventListener("click", myFunction);
If you give the button an ID, this can be replaced with:
document.getElementById("button-id").addEventListener(...)
The third issue
You're passing 'carrier' directly to your function, but my guess is that you want to read the value from the <select> element. To do this, you should use document.getElementById and .value to read the select:
var carrier = document.getElementById("carrier").value;
Once you've done that, you can utilize carrier in your fetch request
The fourth issue
As others have already mentioned in the comments, you should avoid calls to document.write. There are books written about why it's bad, but the proper answer is to use the DOM API to modify elements on the page. For instance:
var p = document.createElement("p");
p.innerHTML = data;
document.appendChild(p);
The final code
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ghibli App</title>
<link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div id="root"></div>
<form>
<select id="carrier">
<option value="carrier">Carrier</option>
<option value="icloud">iCloud</option>
</select>
<button id="button-id">Submit</button>"
</form>
<script src="scripts.js"></script>
</body>
</html>
script.js
function myFunction(event){
event.preventDefault();
var carrier = document.getElementById("carrier").value;
fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999&carrier=' + carrier)
.then(response => response.text())
.then(data => {
var p = document.createElement("p");
p.innerHTML = data;
document.appendChild(p);
});
}
document.getElementById("button-id").addEventListener("click", myFunction);
There are two pages in my tomcat server.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button onclick="onBtnClick()">jump to child</button>
<script>
const msg = {
name:'index.html',
ifor:'I am your parent!'
};
function onBtnClick() {
const childWindow = window.open('./child.html');
childWindow.msg = msg
}
</script>
</body>
</html>
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="msg-panel"></div>
<script>
const msgPanel = document.querySelector('#msg-panel');
msgPanel.innerHTML = `<span>${msg.name}</span><br><span>${msg.ifor}</span>`
console.log(window.msg);
</script>
</body>
</html>
I want to pass some message( the msg Object in index.html) from index.html to child.html, by the way above.
When I click the button in index.html to open the child.html, sometimes I can get the msg object in child.html, but sometimes I can't.
make the button type="button"
you set the message after opening. Sometimes the computer will be faster and not pass the message before it is shown. Use a timeout to show the message in the child OR
store the message in sessionStorage before calling window.open OR
have the child read the message from the parent:
const msgPanel = document.querySelector('#msg-panel');
msgPanel.innerHTML = `<span>${opener.msg.name}</span><br><span>${opener.msg.ifor}</span>`
console.log(window.msg);
Because you sometimes get that message and sometimes not try to put code from script from index.html in this:
document.addEventListener("DOMContentLoaded", function(event) {
//your code...
}
I think your html is not loaded and you click the button too fast.
Although this is already solved. Another alternative for sending data to a child would be localstorage. Getting and setting is really easy and IE11 is also supported.
localStorage.setItem('msg', 'something important');
let msg = localStorage.getItem('msg');
With that you would also have the ability to send data back and forth by setting event listeners on the localstorage change event like
window.addEventListener('storage', function(e) {
//do some cool stuff here
}
Just in case you want to have a more complex exchange between parent and child.