Error: Unable to assign innerHTML to a null object

Yesterday, I spent a considerable amount of time attempting to troubleshoot an error without any success. Despite everything else functioning correctly, the error keeps me concerned, prompting me to revisit and refactor the code. I've experimented with various solutions, such as changing variable names, using window.addEventListener, reverting to older versions, and debugging each step one by one. Nonetheless, nothing seems to resolve the issue. The error message specifically points to a problem occurring at setupDay.

Uncaught (in promise) TypeError: Cannot set properties of null (setting 'innerHTML') at setupDay  (getWeatherInfo.js:37:23)

Below is the snippet of code:

getWeatherInfo.js



import { FetchWrapper } from "./fetchWrapper.js";

const apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const unit = "imperial";
const form = document.querySelector("#weatherForm");
const zip = document.querySelector("#zipcode");
const country = "us";

// Event listener for form submit
form.addEventListener("submit", (event) => {
  event.preventDefault();
  getWeatherInfo(zip.value);
});

const geoAPI = new FetchWrapper("https://api.openweathermap.org/geo/1.0/");
const API = new FetchWrapper("https://api.openweathermap.org/data/2.5/");

const getWeatherInfo = (zip) => {
  const endpoint = `zip?zip=${zip},${country}&appid=${apiKey}&units=${unit}`;
  geoAPI.get(endpoint).then((data) => {
    const lat = data.lat;
    const lon = data.lon;
    const weatherEndpoint = `weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=${unit}`;
    const fiveDayEndpoint = `forecast?lat=${lat}&lon=${lon}&appid=${apiKey}&units=${unit}`;

    // ----------------- Current Weather ----------------- //

    API.get(weatherEndpoint).then((data) => {

      function setupDay(value) {
        let tempValue = document.querySelector("#weather-body-temp-value");
        tempValue.innerHTML = value.main.temp;

        let feelsLike = document.querySelector("#weather-body-feels-like-value");
        feelsLike.innerHTML = value.main.feels_like;

        let weatherDescription = document.querySelector("#weather-body-description");
        weatherDescription.innerHTML = value.weather[0].description;

        let weatherIcon = document.querySelector("#weather-body-description-icon");
        weatherIcon.innerHTML = `<img src="http://openweathermap.org/img/wn/${value.weather[0].icon}@2x.png">`;

        let windSpeed = document.querySelector("#weather-body-wind-value");
        windSpeed.innerHTML = value.wind.speed;

        let cityName = document.querySelector("#weather-body-city-value");
        cityName.innerHTML = value.name;

        let sunrise = document.querySelector("#weather-body-sunrise-value");
        sunrise.innerHTML = unixTimeConvertor(value.sys.sunrise);

        let sunset = document.querySelector("#weather-body-sunset-value");
        sunset.innerHTML = unixTimeConvertor(value.sys.sunset);
      }
  
      setupDay(data);
    });

    // ----------------- 5 Day Forecast ----------------- //

    API.get(fiveDayEndpoint).then((data) => {
      const day1 = data.list[0];
      const day2 = data.list[8];
      const day3 = data.list[16];
      const day4 = data.list[24];
      const day5 = data.list[32];
      
      function setupDays (value, dayNumber)  {
        let temperature = document.querySelector("#day" + dayNumber);
        temperature.innerHTML = value.main.temp;

        let humidity = document.querySelector("#day" + dayNumber + "-humidity");
        humidity.innerHTML = value.main.humidity;

        let description = document.querySelector("#day" + dayNumber + "-description");
        description.innerHTML = value.weather[0].description;

        let icon = document.querySelector("#day" + dayNumber + "-icon");
        icon.innerHTML = `<img src="http://openweathermap.org/img/wn/${value.weather[0].icon}@2x.png">`;
      };
      setupDays(day1, 1);
      setupDays(day2, 2);
      setupDays(day3, 3);
      setupDays(day4, 4);
      setupDays(day5, 5);
    });
  });
};

const unixTimeConvertor = (unixTimestamp) => {
  const dateObject = new Date(unixTimestamp * 1000);
  const date = dateObject.toLocaleString("en-US", {
    hour: "numeric",
    minute: "numeric",
    second: "numeric",
  });
  return date;
};

fetchWrapper.js

//fetchwrapper.js
export class FetchWrapper {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  get(endpoint) {
    return fetch(this.baseURL + endpoint).then((response) => {
      return response.json();
    });
  }
}

getFiveDayWeather.html


<!DOCTYPE html>
...

getCurrentWeather.html


<!DOCTYPE html>
...

Answer №1

When working with two different HTML pages that have elements with unique IDs, it's important to consider how JavaScript functions may fail when attempting to fetch elements unconditionally.

For example, if you are on the page getFiveDayWeather.html, calling setupDay() will lead to failure because there is no element with ID #weather-body-temp-value. Similarly, if you are on getCurrentWeather.html, calling setupDays() will fail due to the absence of #day1.

Despite these errors occurring within promise callbacks, subsequent code execution remains unaffected as the function terminates at the point of error. To resolve this issue, it is advisable to conditionally execute either API.get(weatherEndpoint) or API.get(fiveDayEndpoint) based on the current HTML page being accessed.

An implementation solution could involve a conditional check like the following:

if(document.querySelector("#weather-body-temp-value"))
{
  // ----------------- Current Weather ----------------- //
  API.get(weatherEndpoint).then((data) => {
    ...
  });
}
else if(document.querySelector("#day1"))
{
  // ----------------- 5 Day Forecast ----------------- //
  API.get(fiveDayEndpoint).then((data) => {
    ...
  });
}
else
{
  // Handle error or display an alert message
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The JavaScript setInterval function does not have the ability to automatically repeat the task

I am attempting to use the setInterval function to fetch data from another website every 10 seconds. However, it is only running for the first time and then stopping. setInterval(fetchData("testtest"), 10000); function fetchData(username){ var xht ...

Tween JS leads to WebGL Context loss

Utilizing Tween.js to animate a lissajous curve in a Three.js render loop has been mostly successful. However, I have encountered an issue after around 70 iterations where WebGL crashes and displays the error message: CONTEXT_LOST_WEBGL: loseContext: conte ...

Encountering difficulties starting npm after deploying NextJS app on Azure App Service

When attempting to deploy a Next.js app from a mono repo to Azure AppService (Linux), I have encountered partial success. The package is visible in Data/SitePackages, but the startup command (npm start) fails to initiate the application. The configuration ...

What is the best way to update object values only when changes occur, and leave the object unchanged if no changes

There is an object named ApiData1 containing key-value pairs, including color values within properties. The colors are updated based on the numberOfProjects value from ApiData2, with specific ranges dictating the color updates. This setup is functioning co ...

Troubleshooting a problem with selecting options in Jquery

Looking for assistance with a jquery script. I have a select dropdown that fetches a list of options via Ajax. When a user clicks on an option, if a certain variable equals 1, an HTML div is added. If the variable changes to another value, the HTML div dis ...

What is the best way to identify when my custom objects collide with the boundaries of the screen?

I need help detecting collisions between my dynamic cards and the screen boundaries. Currently, when the cards go out of view, I want them to bounce back upon hitting the screen edge. How can I identify these collisions in my code? As of now, the cards ...

Inadequate data being sent to the server from Angular2 post request

Currently, I have a form field whose value I am passing to a service as this.form.value. However, when I log this.form.value on the console, I see Object { email: "zxzx", password: "zxzxx" }. Despite this, when I send the same data to the service and make ...

Why does the JavaScript code work perfectly in Mozilla, but show an unknown runtime error in IE6?

When building my page, I implemented a simple blow up trick. Initially, the div is set as hidden, and when the image is clicked, a blow up effect occurs with an overlay image in the background. The JavaScript function updates the innerHTML. While this work ...

What is the best way to delete a model from a Backbone.Collection?

How can I properly remove a model from a collection in Backbone.js? var item = new Backbone.Model({ id: "01", someValue: "blabla", someOtherValue: "boa" }); var list = new Backbone.Collection([item]); list.get("01").destroy(); After calling ...

Using external JavaScript within an EJS template

I'm facing some difficulties with EJS. I want to include a javascript file in my template, but I am unsure of how to properly implement it. Below is the code I have so far: game.ejs : <!DOCTYPE html> <html> <head> <t ...

Dynamically generate checkbox options based on dropdown menu selection

I'm currently designing a form that will dynamically display checkboxes within a div based on media files uploaded by a specific usergroup. Essentially, when a user chooses the group name from a dropdown menu, all relevant media files will be listed a ...

Creating a Dynamic Clear Button for a Text Area in Angular

Working on my Angular application, I have implemented a form with a textarea element. My goal is to incorporate a clear button inside the textarea element that should: Appear only when the textarea is focused Disappear when the textarea is out of focus ( ...

CORS has restricted access to the XMLHttpRequest, despite the backend being configured correctly

I have a Flask backend integrated with React frontend. I encountered an issue while attempting to make a POST request to my backend. The error message states: Access to XMLHttpRequest at 'http://127.0.0.1:5000/predict' from origin 'http://lo ...

Problem with HTML relative paths when linking script sources

Having trouble with a website I constructed using Angular. The problem lies in the references to javascript files in index.html. The issue is that the paths in the HTML are relative to the file, but the browser is searching for the files in the root direct ...

Tips for loading a webpage when a button is clicked with the help of jQuery AJAX and PHP:

Is it possible to dynamically load a page on button click, pass data to the new page using jQuery AJAX, and place the received value in an input field within the loaded page? Basically, the scenario is as follows: A button named "Something" triggers the l ...

What is the best way to notify the user if the percentage entered is not a numeric value?

My role is to notify the user when the entered value exceeds the acceptable range: if (document.myForm.outputPercentage.value <= 0 || document.myForm.outputPercentage.value >= 100) { alert( "Please enter a percentage between 1 and 100 ...

Utilize JSON or an environment file to pass dynamic values to an npm script

I've been working on setting up an npm script for deploying react apps (specifically using create-react-app). However, I'm facing a challenge in setting the S3 bucket url string in either an environment variable or JSON file. This way, I can easi ...

Issue with navigation menu button functionality on mobile devices

Whenever I attempt to access my website on a small device, the bootstrap navbar is supposed to collapse. However, the button doesn't seem to be working. Any assistance would be greatly appreciated as this is the one issue I'm struggling with. I&a ...

When using Angular, the "contenteditable" attribute is rendered ineffective if the element is added through the use of "[innerHTML]"

I recently encountered a surprising issue with the contenteditable attribute in Angular. I have an object containing HTML code as values: public json_html = { "button1":"<p contenteditable='true'>first section</p>", "button2":"&l ...

What is the best way to include an Observable in this function?

Every time I send a set of credentials to my API and receive the data that needs to be stored, I encounter an error during the login process. Error: TypeError: You have provided an invalid object when a stream was expected. You can provide an Observable ...