Problem with .innerHtml and .require()

Hi.

I want to change what Chrome is displaying, from “Hi” to “Hello World”. (It’s just a <h2> element).
It works only when I comment .require()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./test.js" async></script>
    <title>Test</title>
</head>
<body>
    <h2>Hi</h2>
    
</body>
</html>
//file name: test.js
// const school=require('./main.js');
const h2=document.querySelector('h2');
h2.innerHTML='Hello world';
//h2.innerHTML= school.name;

You can see in JS that my original purpose was to display school.name. However, it wasn’t working.

What’s going on here? XD

The browser doesn’t have a built-in require like node does. For this reason, if you try to run it with the require line, it results in an error on that line and the rest of the script doesn’t run.

It’s still possible to use multiple javascript files if you’re careful about the order they are loaded and whether it should be async or defer.

1 Like

Most modern browsers will understand the use of import, but require is a Node-specific keyword which pre-dates the introduction of import to the ECMAScript standard.

2 Likes

Hi, I tried this but it’s still not working: (I’m using Google Chrome)

// I used `export default  lorraineHansbury` inside main.js;
import lorraineHansbury from './main.js';
const name= lorraineHansbury.name;

const h2 = document.querySelector('h2');
h2.innerHTML= name;

Should that be exported as an object?

{lorraineHansbury}

I know, dumb question, but hey… Still not completely competent when it comes to modules.

3 Likes

Hi. Still not working {lorraineHansbury} :cry:

I’m gonna try using defer on <script> elements.

Please link to the exercise so we can gain better context. It seems to me that it is already an object (instance of School class?) but I don’t recall the lesson.

1 Like

Yes, it is an instance of School class, and Primary is the child class. lorraineHansbury is an object.

Primary {
  _name: 'Lorraine Hansbury',
  _level: 'primary',
  _numberOfStudents: 514,
  _pickupPolicy: 'Students must be picked up by a parent, guardian, or a family member over the age of 13.'
}

What I’m trying to do is not an excersice from codeacademy, it’s something that just came to my mind. Try to export lorraineHansbury from main.js to test.js, and inside test.js unse innerHTML to display lorraineHansbury.name in the browser.

You might need a getter in your Primary class since the properties are all written as backing variables (which we would not wish to access directly).

class School{
    constructor(name,level,numberOfStudents){
        this._name= name;
        this._level= level;
        this._numberOfStudents= numberOfStudents;
    }
    get name(){
        return this._name;
    }
    get level(){
        return this._level;
    }
    get numberOfStudents(){
        return this._numberOfStudents;
    }
.
.
.
class Primary extends School{
    constructor(name, numberOfStudents, pickupPolicy){
        super(name, 'primary', numberOfStudents);
        this._pickupPolicy= pickupPolicy;
    }
    get pickupPolicy(){
        return this._pickupPolicy;
    }
}

I used it.

And it’s still not picking it up. Just off I don’t know what to suggest without doing a bit of a review of modules. You wouldn’t have a link to that lesson, would you?

Of course, Here it goes.

I’m gonna finish the lesson first XD, then I’m gonna try again.

Thanks

1 Like

It worked using:

<script src="./main.js" defer></script>
    <script src="./test.js" defer></script>

Interesting. That looks like one possible solution. If you care to show us your complete code we can have a look at over the weekend after I’ve had a chance to review the module lessons. There may well be another solution that doesn’t involve deferral of scripts.

1 Like

Here’s a sample that uses type="module" when bringing in the Javascript file in the HTML so that the script itself can then import the other Javascript file. I double tested this in repl.it and then checked in Chrome and Firefox.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="module" src="./script.js" defer></script>
    <title>Test</title>
</head>
<body>
    <h2>Hi</h2>
    
</body>
</html>

script.js

import school from './main.js';

const h2=document.querySelector('h2');
h2.innerHTML= school.name;

main.js

const school = {
  name: 'Codecademy University',
};

export default school;

I only named the Javascript files so it matches your original post.

3 Likes

Sure!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <!-- <script src="./main.js" defer></script> -->
    <script src="./test.js" async></script>
    <title>Test</title>
</head>
<body>
    <h2>Hi</h2>
</body>
</html>
// file: test.js
import lorraineHansbury from './main.js';
const name= lorraineHansbury.name;

const h2 = document.querySelector('h2');

h2.innerHTML= name;
//file: main.js
class School{
    constructor(name,level,numberOfStudents){
        this._name= name;
        this._level= level;
        this._numberOfStudents= numberOfStudents;
    }
    get name(){
        return this._name;
    }
    get level(){
        return this._level;
    }
    get numberOfStudents(){
        return this._numberOfStudents;
    }
    set numberOfStudents(number){
        isNaN(number) ? console.log('Invalid input: numberOfStudents must be set to a Number.') : this._numberOfStudents= number  ;
    }
    quickFacts(){
        console.log(`${this.name} educates ${this.numberOfStudents} students at the ${this.level} school level.`);
    }
    static pickSubstituteTeacher(subtituteTeachers){
        const randomTeacher = Math.floor(Math.random()*subtituteTeachers.length);
        return subtituteTeachers[randomTeacher];
    }
}

class Primary extends School{
    constructor(name, numberOfStudents, pickupPolicy){
        super(name, 'primary', numberOfStudents);
        this._pickupPolicy= pickupPolicy;
    }
    get pickupPolicy(){
        return this._pickupPolicy;
    }
}

class Middle extends School{
    constructor(name, numberOfStudents){
        super(name, 'middle', numberOfStudents);
    }
}

class High extends School{
    constructor(name, numberOfStudents, sportsTeams){
        super(name, 'high', numberOfStudents);
        this._sportsTeams= sportsTeams;
    }
    get sportsTeams(){
        return this._sportsTeams;
    }
}

const lorraineHansbury= new Primary('Lorraine Hansbury', 514, 'Students must be picked up by a parent, guardian, or a family member over the age of 13.');

// console.log(lorraineHansbury)
export default lorraineHansbury;

I’m gonna finish Module lesson.

2 Likes

Is ‘defer’ necessary if the script is written in the body, just before the ENDTAG?

No, defer wouldn’t be necessary if the script were just before the endtag </body>. In that case, we’re guaranteed that <h2> has already been loaded so the selector will work.

I’ve noticed outside of the lesson / exercises about defer / async, most Codecademy sample code in the other courses still load the script at the end of the body.

1 Like

It’s been a practice that’s been used for a good long while as an alternative to defer It also affords other resources to precede the script download so CSS is also in place.

1 Like

I just copied the code and rename test.js to script.js. However, it’s still not working for me.

Probably I should update my Chrome or something XD