Trying to get value of 'sunrise' from api

Hi everyone. I have done tons of research and cannot find the answer for this and am very new to JS. I am am using the Sunset and sunrise times API - Sunrise-Sunset.org api and am trying to extract the value of ‘sunrise’ and ‘sunset’ from the API. I have this so far:

getText("https://api.sunrise-sunset.org/json?lat=-29.883333&lng=31.049999");

async function getText(file) {
  let x = await fetch(file);
  let y = await x.text();
  document.getElementById("api-stuff").innerHTML = y;
}

which is printing out this:

{“results”:{“sunrise”:“4:43:27 AM”,“sunset”:“3:04:47 PM”,“solar_noon”:“9:54:07 AM”,“day_length”:“10:21:20”,“civil_twilight_begin”:“4:18:42 AM”,“civil_twilight_end”:“3:29:33 PM”,“nautical_twilight_begin”:“3:49:05 AM”,“nautical_twilight_end”:“3:59:10 PM”,“astronomical_twilight_begin”:“3:20:02 AM”,“astronomical_twilight_end”:“4:28:12 PM”},“status”:“OK”}

The problem is that I just want to get the value of ‘sunrise’ and ‘sunset’ and can’t seem to extract them no matter what I do. I have tried to use:

document.getElementById("api-stuff").innerHTML = y.results.sunrise;

but it returns nothing.

In comparison, if I set up a quick test:

const myObj = {"results":{"sunrise":"4:43:27 AM","sunset":"3:04:47 PM","solar_noon":"9:54:07 AM","day_length":"10:21:20","civil_twilight_begin":"4:18:42 AM","civil_twilight_end":"3:29:33 PM","nautical_twilight_begin":"3:49:05 AM","nautical_twilight_end":"3:59:10 PM","astronomical_twilight_begin":"3:20:02 AM","astronomical_twilight_end":"4:28:12 PM"},"status":"OK"}

document.getElementById("demo").innerHTML = myObj.results.sunrise;

it all works perfectly. I honestly have no clue why it is not working in the real life example.

I figured it out!

async function getText(file) {
  let x = await fetch(file);
  let y = await x.json();
	let sunset = y["results"]["sunset"];
	document.getElementById("api-stuff").innerHTML =sunset;	
}
2 Likes

Hi everyone, I am still having a problem with the above, but with a new API, the 7timer API. Could someone help me to get the information from this API. It shows a 7 day forecast for the below code. I don’t know how to iterate through the 7 days and show them. Can anyone help me, I have tried everything and nothing work. I tried for in loops, changing the ‘await x.text()’ to ‘await x.json()’ and then changing it to an array and trying to extract the values. Can anyone help?

weatherApi( "http://www.7timer.info/bin/api.pl?lon=31.049999&lat=-29.883333&product=astro&output=json&unit=metric");
		
	async function weatherApi(file) {
			let x = await fetch(file);
			let y = await x.text();
			
		
			
		document.getElementById("news-info").innerHTML = y;
	}

Why are you using .text() instead of .json() this time? That endpoint returns JSON data…

Just change the above line into following:
Mod Edit: SOLUTION REDACTED

I know, I am just showing the text for now so that you can see this output that I am trying to access:

{ “product” : “astro” , “init” : “2022060606” , “dataseries” : [ { “timepoint” : 3, “cloudcover” : 6, “seeing” : 6, “transparency” : 4, “lifted_index” : 6, “rh2m” : 10, “wind10m” : { “direction” : “NE”, “speed” : 3 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 6, “cloudcover” : 4, “seeing” : 6, “transparency” : 4, “lifted_index” : 6, “rh2m” : 10, “wind10m” : { “direction” : “NE”, “speed” : 4 }, “temp2m” : 21, “prec_type” : “none” }, { “timepoint” : 9, “cloudcover” : 1, “seeing” : 6, “transparency” : 4, “lifted_index” : 2, “rh2m” : 11, “wind10m” : { “direction” : “NE”, “speed” : 4 }, “temp2m” : 21, “prec_type” : “none” }, { “timepoint” : 12, “cloudcover” : 1, “seeing” : 6, “transparency” : 4, “lifted_index” : 6, “rh2m” : 11, “wind10m” : { “direction” : “NE”, “speed” : 4 }, “temp2m” : 21, “prec_type” : “none” }, { “timepoint” : 15, “cloudcover” : 1, “seeing” : 6, “transparency” : 4, “lifted_index” : 6, “rh2m” : 11, “wind10m” : { “direction” : “N”, “speed” : 3 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 18, “cloudcover” : 1, “seeing” : 7, “transparency” : 3, “lifted_index” : 6, “rh2m” : 11, “wind10m” : { “direction” : “N”, “speed” : 3 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 21, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 10, “rh2m” : 8, “wind10m” : { “direction” : “NW”, “speed” : 2 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 24, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 15, “rh2m” : 6, “wind10m” : { “direction” : “NW”, “speed” : 2 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 27, “cloudcover” : 1, “seeing” : 6, “transparency” : 2, “lifted_index” : 10, “rh2m” : 5, “wind10m” : { “direction” : “SW”, “speed” : 2 }, “temp2m” : 23, “prec_type” : “none” }, { “timepoint” : 30, “cloudcover” : 1, “seeing” : 6, “transparency” : 2, “lifted_index” : 6, “rh2m” : 6, “wind10m” : { “direction” : “S”, “speed” : 2 }, “temp2m” : 23, “prec_type” : “none” }, { “timepoint” : 33, “cloudcover” : 1, “seeing” : 7, “transparency” : 3, “lifted_index” : 6, “rh2m” : 8, “wind10m” : { “direction” : “S”, “speed” : 2 }, “temp2m” : 22, “prec_type” : “none” }, { “timepoint” : 36, “cloudcover” : 1, “seeing” : 7, “transparency” : 3, “lifted_index” : 6, “rh2m” : 8, “wind10m” : { “direction” : “SW”, “speed” : 2 }, “temp2m” : 22, “prec_type” : “none” }, { “timepoint” : 39, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 10, “rh2m” : 8, “wind10m” : { “direction” : “W”, “speed” : 2 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 42, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 10, “rh2m” : 8, “wind10m” : { “direction” : “W”, “speed” : 2 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 45, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 15, “rh2m” : 7, “wind10m” : { “direction” : “NW”, “speed” : 2 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 48, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 15, “rh2m” : 7, “wind10m” : { “direction” : “NW”, “speed” : 2 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 51, “cloudcover” : 1, “seeing” : 6, “transparency” : 2, “lifted_index” : 10, “rh2m” : 5, “wind10m” : { “direction” : “N”, “speed” : 2 }, “temp2m” : 21, “prec_type” : “none” }, { “timepoint” : 54, “cloudcover” : 1, “seeing” : 6, “transparency” : 3, “lifted_index” : 6, “rh2m” : 8, “wind10m” : { “direction” : “NE”, “speed” : 3 }, “temp2m” : 22, “prec_type” : “none” }, { “timepoint” : 57, “cloudcover” : 1, “seeing” : 6, “transparency” : 3, “lifted_index” : 6, “rh2m” : 9, “wind10m” : { “direction” : “NE”, “speed” : 3 }, “temp2m” : 21, “prec_type” : “none” }, { “timepoint” : 60, “cloudcover” : 1, “seeing” : 6, “transparency” : 3, “lifted_index” : 6, “rh2m” : 10, “wind10m” : { “direction” : “NE”, “speed” : 4 }, “temp2m” : 22, “prec_type” : “none” }, { “timepoint” : 63, “cloudcover” : 1, “seeing” : 6, “transparency” : 3, “lifted_index” : 6, “rh2m” : 11, “wind10m” : { “direction” : “NE”, “speed” : 4 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 66, “cloudcover” : 1, “seeing” : 6, “transparency” : 3, “lifted_index” : 10, “rh2m” : 10, “wind10m” : { “direction” : “N”, “speed” : 4 }, “temp2m” : 20, “prec_type” : “none” }, { “timepoint” : 69, “cloudcover” : 1, “seeing” : 7, “transparency” : 2, “lifted_index” : 10, “rh2m” : 8, “wind10m” : { “direction” : “N”, “speed” : 3 }, “temp2m” : 18, “prec_type” : “none” }, { “timepoint” : 72, “cloudcover” : 1, “seeing” : 6, “transparency” : 2, “lifted_index” : 15, “rh2m” : 6, “wind10m” : { “direction” : “N”, “speed” : 3 }, “temp2m” : 17, “prec_type” : “none” } ] }

So now, in my code, I will change that line to await x.json(); so that I can iterate through the result and show it, and then style it eventually. So what I need is something that will eventually allow me to populate my HTML like below:


<div class="daily-weather">
<h2>Day : 1</h2>
cloudcover: 1st entry
wind: 1st entry
speed: 1st entry
</div>

<div class="daily-weather">
<h2>Day : 2</h2>
cloudcover: 1st entry
wind: 1st entry
speed: 1st entry
</div>

<div class="daily-weather">
<h2>Day : 3</h2>
cloudcover: 1st entry
wind: 1st entry
speed: 1st entry
</div>

<!--- etc -->

So I need to be able to draw the values from the JSON output separately so I can add them to my daily-weather div.

Usually this should work, but doesn’t:

... let y = await x.json();
document.getElementById("cloud-cover").innerHTML = y.dataseries.cloudcover;
// should output 6 for the first value, but just comes out blank.

I have also tried to use iterations, which I think is probably what I should do as there are more than one ‘cloudcover’ keys and values, but everything I tried with that didn’t output anything.
I hope this makes more sense now how I am trying to extract this data.

If you break this problem into a smaller problem, do you think you could handle it?

dataseries is an array of multiple objects, but let’s just try working with one. Here’s the first object.

{
  timepoint: 3,
  cloudcover: 6,
  seeing: 6,
  transparency: 4,
  lifted_index: 6,
  rh2m: 10,
  wind10m: { direction: "NE", speed: 3 },
  temp2m: 20,
  prec_type: "none",
}

How would you turn this one object into the HTML you want? I don’t think innerHtml is the right choice.

Hi Colinthornton, thank you for your reply. So I think this should work, and in theory in my head it produces results, but when I run it, it shows nothing. am I on the right track with the for loop? I am not sure what I am doing wrong:

weatherApi( "http://www.7timer.info/bin/api.pl?lon=31.049999&lat=-29.883333&product=astro&output=json&unit=metric");
		
	async function weatherApi(file) {
			let x = await fetch(file);
			let y = await x.json();
			const yParsed = JSON.parse(y);
			
			let myArray = "";
			for (let i in yParsed.dataseries) {
				myArray += yParsed.dataseries.cloudcover[i] + "<br />";
			}
		
			
		document.getElementById("news-info").innerHTML = myArray;
	}

The above should show all the cloudcover results one after another with a line break between each one.

You mean that this is your final goal, right?

I don’t want to be discouraging but it looks like you’ve got some more fundamental misunderstandings about JavaScript at this point. You really need to make sure you understand the type of the data that’s returned from methods, or else how are you going to work with them properly?

let y = await x.json();

Okay, you parsed the return data as JSON, and saved that object to the variable y

const yParsed = JSON.parse(y);

…and then parsed it again? y is already an object, so there’s no need to convert it to an object.

let myArray = "";

This is a big naming issue in my opinion. It’s named “array”, but it’s actually a string.

for (let i in yParsed.dataseries) {

for…in loops are for looping over all the keys in an object. Are you sure that a for…in loop is what you want to use for whatever type of dataseries is? Hint, dataseries is an array.

Yes, the final goal is to show each days weather in it’s own div. I believe that the API produces a kind of string that converts easily into a Javascript object that can be accessed through object notation and through an array.

I see now that I have ‘parsed’ it twice. OOOPS! I am currently studying JSON now too so I can get this right.

So a standard Javascript array retrieval would be the for loop, is that correct, like something down below:

for (let i = 0; i < somethingHere.length; i++) {
  text += theValue[i];
}

or through a foreach loop? I don’t know which way gets the key and value which I realise now is what I am trying to do.

So just to add here, the following image is an example shown on how to loop through an array. This is where I am getting the ‘for in’ loop idea, so I am a bit confused why this would be incorrect:

image