Beginner Question

Hello,

I’m doing my first javascript project, essentially a page with a search bar for a location, which will then use a weather API to get the forecast and display on the page below the search box

I’ve done the search bar, search button and API, however how do I get the data from the script section back into my HTML page? I’ve seen a few examples, but I don’t quite get how it would work in my example. I’m using onclick to run the api function, do I pass the output object back to HTML through the function? If so how do I do that when calling the function with onclick?

Sure there is a simple way.

<!DOCTYPE html>
<html>
<body>
<h1>Weather Please</h1>
<p>Enter a location to search below</p>
<p>Location - <input type="text" id="search" size="15" name ="search"></p>

<button type="button" onclick ="GetResults()">Get Weather</button>
<script>
	function GetResults(){
		var searchTerm
		var output
		var header
		searchTerm=document.getElementById('search').value
		header='http://api.openweathermap.org/data/2.5/weather?q='+searchTerm+'&appid=464c773f8caef5891acdb004a16176f1'
				
		output = fetch(header)
		console.log(searchTerm)
		console.log(header)
		
		
	}
</script>		
<p output></p>
</body>
</html>
1 Like

So you’re close, but we need to get… juuuust a little bit deeper on fetch.

The following will essentially be a review/retelling of Using the Fetch API - Web APIs | MDN (mozilla.org), for reference.

fetch() will return what Javascript calls a Promise. A promise is… well, like a promise. Javascript is telling your code “Okay, you’ve told me what you want me to do. I’m going to go away and try and do it; you keep going. If you want to keep an eye on the request, here’s a ticket for you to reference.”

output, in your case, will contain that ticket.

We don’t actually want the ticket, we want the result of the operation. Javascript has a way of handling this idea; .then.

.then, when attached to a Promise, says “When this Promise is done, then do the following…”

So what we need to do is attach a then to your promise.

fetch(header)
.then(/*We handle the contents of this next.*/);

(The line break isn’t actually necessary, but it makes it a little more readable, especially when we start filling out the contents of the then handler.)

So, we’ve now told the javascript we want it to fetch something, and then when it’s done, we’re going to do something with the result. What do we do with it? How do we access it?

the contents of a then invocation should be a function. That function should take 1 argument, which is the result from the promise. In the case of fetch, the result of the promise is the HTML of the response. Based on you saying that it’s an object you’re returning, am I to interpret that it’s a JSON response?

If so, read on; if not, skip the next paragraph.

If the return is a json, generally speaking what you’ll do is first interpret the result through the JSON parser. This is done so that you can catch an error if one exists. So you’ll actually run two thens chained together (This is doable because technically, then also returns its own Promise, so the second then attaches to the first then’s promise, and waits for it to be done and return a value). This becomes:

fetch(header)
.then(response => response.json())
.then(/* read on */);

(This is a single-line, silent-return, lambda function. If you dont understand this syntax, let us know.)

Once we have our result, what do we do with it? Based on your HTML, you want to stick it into that paragraph tag. Firstly, I would suggest adding an id to your paragraph tag. I will assume you have called it output for the purposes of this code.

You already know how to get an element by its ID, so I will skip that part; what I will say is that an element that you have gotten that is a text container (such as a <p>), has a property called .innerHTML. That property is writable.

So, we now have our data, we have our target element, and we want to put it into that element once we’ve resolved the promise.
.then(data => document.getElementById("output").innerHTML = data)
(or if the data is a json, and you’ve translated it into an object using the parser above, you’ll set the innerHTML to the correct property of that object; data.somevalue).

Give it a try, see how you get on.

4 Likes

Excllent, thank you for this!

I am a lot closer now :slight_smile: I’m just a little stuck on the last part. The output that is written to my output paragraph is "[object Object] rather than the parsed JSON. Using console.log it did output the full text, but how do I write the full text in the HTML paragraph?

<!DOCTYPE html>
<html>
<body>
<h1>Weather Please</h1>
<p>Enter a location to search below</p>
<p>Location - <input type="text" id="search" size="15" name ="search"></p>

<button type="button" onclick ="GetResults()">Get Weather</button>
<script>
	function GetResults(){
		var searchTerm
		var output
		var header
		searchTerm=document.getElementById('search').value
		header='http://api.openweathermap.org/data/2.5/weather?q='+searchTerm+'&appid=464c773f8caef5891acdb004a16176f1'
				
		fetch(header)
		.then(response => response.json())
		.then(data => document.getElementById("output").innerHTML = data);
		
		console.log(searchTerm)
		console.log(header)
		
		
	}
</script>		
<p id='output'></p>
</body>
</html>

Without knowing what your object looks like, I can’t quite give you a straightforward “do this”, but… the above is what you need to do.

Ah I see, I’ve put data.clouds.all which has given me results from the json :slight_smile:

Thank you!

1 Like