
could someone please lead me to the right direction with my JS here?
I have been struggling to find out why my JS weather widget will not update the image strip to the correct icon. I have this :
<script>fetch('https://api.open-meteo.com/v1/forecast?latitude=39.082222&longitude=-77.482222&daily=temperature_2m_max,temperature_2m_min&hourly=temperature_2m&timezone=auto&current_weather=true&forecast_days=1')
.then(response => response.json())
.then(data => {
console.log(data);
const weather = data.current_weather;
const daily = data.daily;
const targetLat = 39.082222;
const targetLon = -77.482222;
console.log('Low (F):', daily.temperature_2m_min[0]);
console.log('High (F):', daily.temperature_2m_max[0]);
console.log('Low (F):', Math.round(daily.temperature_2m_min[0] * 9/5 + 32));
console.log('High (F):', Math.round(daily.temperature_2m_max[0] * 9/5 + 32));
const targetCity = 'Lansdowne, VA';
const currentTemp = Math.round(weather.temperature * 9/5 + 32);
const iconCode = weather.weathercode;
// FIX: If currentTemp is much higher than the morning low, we adjust the displayed low
// to reflect the expected upcoming night low instead of the passed morning cold.
let lowF = Math.round(daily.temperature_2m_min[0] * 9/5 + 32);
console.log('Low (F):', lowF);
const lowTemp = lowF;
const highTemp = Math.round(daily.temperature_2m_max[0] * 9/5 + 32);
const weatherDiv = document.getElementById('weather');
console.log('Weather widget loaded completely.');
console.log('Icon code:', iconCode);
});
const weatherDiv = document.getElementById('weather');
const img = new Image();
img.src = 'https://i.ibb.co/WptyQH9y/image-strip-weather.jpg';
img.onload = () => console.log('Image loaded!');
img.onerror = () => console.log('Image error!');
function weatherCodeToIconURL(code) {
console.log('wttr code:', code, typeof code);
// FIXED: Translation map connecting Open-Meteo codes directly to your image strip positions
const openMeteoToSprite = {
0: "01d", // Sunny / Clear Sky -> First Icon
1: "02d", // Mainly Clear -> Second Icon
2: "02d", // Partly Cloudy -> Second Icon
3: "03d", // Overcast -> Third Icon (Your default)
45: "50d", // Fog -> Fog/Mist Icon
48: "50d", // Depositing Rime Fog -> Fog/Mist Icon
51: "09d", // Drizzle -> Light Rain Icon
53: "09d",
55: "09d",
61: "09d", // Slight Rain -> 4th/5th Rain Cloud Icon
63: "10d", // Moderate Rain -> Heavier Rain Icon
65: "10d", // Heavy Rain
71: "13d", // Snow Fall -> Snow Cloud Icon
73: "13d",
75: "13d",
80: "09d", // Rain Showers
81: "10d",
82: "10d",
95: "11d", // Thunderstorm -> Lightning/Storm Icon
96: "11d",
99: "11d"
};
// 1. ADD THIS SPECIFIC LINE BACK RIGHT HERE:
const spriteKey = openMeteoToSprite[code] || '03d';
// FIXED: Crisp percentage shifts that line up flawlessly when the image is scaled to cover the box
const positions = {
"01d": "0px 0px", // Sun
"01n": "0px 0px",
"02d": "-120px 0px", // Sun/Cloud
"02n": "-120px 0px",
"03d": "-240px 0px", // Cloud
"03n": "-240px 0px",
"09d": "-360px 0px", // Rain
"09n": "-360px 0px",
"10d": "-480px 0px", // Rain variation
"10n": "-480px 0px",
"11d": "-600px 0px", // Thunderstorm
"11n": "-600px 0px",
"13d": "-720px 0px", // Snow
"13n": "-720px 0px",
"50d": "-720px 0px",
"50n": "-720px 0px"
};
// CRITICAL CHANGE: We wrap the final variable so it fits your string perfectly
const pos = positions[spriteKey];
if (pos) {
// FIXED: Added transform: scale(2.5) to magnify the icon to a clear, readable size
return \<div style="display: inline-block; width: 3em; height: 3em; background: url('https://i.ibb.co/WptyQH9y/image-strip-weather.jpg') no-repeat center; background-position: ' + pos + '; background-size: auto; transform: scale(1.5); vertical-align: middle;"></div>`;`
}
// ADD THESE THREE LINES RIGHT HERE BELOW IT:
return 'Unknown code';
}
async function getWeather(lat, lon, city) {
var targetCity = city || 'Lansdowne';
var targetLat = lat || 39.082222;
var targetLon = lon || -77.482222;
var base = 'https://api.open-meteo.com/v1/forecast';
var query = '?latitude=' + targetLat + '&longitude=' + targetLon + '&daily=temperature_2m_max,temperature_2m_min&current=weather_code&timezone=auto&current_weather=true&forecast_days=2';
var url = base + query;
try {
var response = await fetch(url);
if (!response.ok) throw new Error('Status: ' + response.status);
var data = await response.json();
console.log('Min:', data.daily.temperature_2m_min[0]);
console.log('Max:', data.daily.temperature_2m_max[0]);
// Extract current conditions
var currentTemp = Math.round(data.current_weather.temperature * 9/5 + 32);
console.log('currentTemp:', currentTemp);
var iconCode = data.current_weather.weathercode;
// Initialize search tracking counters
var trueHigh = -Infinity;
var trueLow = Infinity;
if (data.daily.temperature_2m_min[0] < trueLow) {
trueLow = data.daily.temperature_2m_min[0];
}
if (data.daily.temperature_2m_max[0] > trueHigh) {
trueHigh = data.daily.temperature_2m_max[0];
}
// Convert raw Celsius trackers into Fahrenheit
var finalHigh = Math.round(data.daily.temperature_2m_max[0] * 9/5 + 32);
var finalLow = Math.round(data.daily.temperature_2m_min[1] * 9/5 + 32);
// FIXED: Directly assign lowTemp and highTemp to use your final calculations
var lowTemp = finalLow;
var highTemp = finalHigh;
weatherDiv.innerHTML = '<p style="font-size: 16px; color: #fff; text-align: center; margin: 0 0 8px 0;">' + targetCity + '</p>' + '<div style="position: relative; text-align: center; margin-bottom: 8px;">' + weatherCodeToIconURL(iconCode) + '<span style="position: absolute; top: 60%; left: 57%; transform: translate(-50%, -50%); font-size: 24px; font-weight: bold; color: #fff; filter: drop-shadow(-3px 0 2px #000);">' + currentTemp + '°F</span>' + '</div>' + '<div style="display: flex; justify-content: space-between; width: 154px; margin: 0 auto;">' + '<p style="font-size: 14px; color: #87CEEB; margin: 0;">Low: ' + lowTemp + '°F</p>' + '<p style="font-size: 14px; color: #FFA07A; margin: 0;">High: ' + highTemp + '°F</p>' + '</div>';
console.log('Weather widget loaded completely. Low Temp:', lowTemp);
// --- NOTE ---
// If you have lines that update 'weatherDiv.innerHTML', ensure they are right here!
} catch (error) {
console.error('Weather widget error:', error);
}
}
function fetchLocationAndWeather() {
// FIXED: Replaced slow browser popups with a silent, instant IP location lookup
fetch('https://ip-api.com')
.then(response => response.json())
.then(data => {
// Sends the visitor's dynamic coordinates and city name directly to your weather builder
getWeather(data.lat, data.lon, data.city);
})
.catch(error => {
console.error('Location error, falling back to Lansdowne:', error);
// Safety fallback: if the IP service fails, default to Lansdowne so the widget doesn't break
getWeather(39.082222, -77.482222, 'Lansdowne');
});
}
// FIXED: Added back the missing '/data/reverse-geocode-client?latitude=' string block
// RUN IT IMMEDIATELY
weatherDiv.innerHTML = 'Loading weather... 🌤️';
setTimeout(function() {
fetchLocationAndWeather();
}, 100);
// SET THE INTERVAL to repeat every minute
setInterval(fetchLocationAndWeather, 60000);</script>
And here is the CSS :
#weather {
display: flex;
flex-direction: column;
font: normal 12px Helvetica, Arial, sans-serif;
color: #fff;
}
And the HTML :
<div id="weather" style="display: flex; flex-direction: column; font: normal 12px Helvetica, Arial, sans-serif; color: #fff; "></div>
I really don't know what to do at this point... I'd appreciate any feedback, corrections, ....etc.