mortvicious
mortvicious

Reputation: 109

Typescript, React: TypeError: Cannot read property 'push' of undefined

Seems like a stupid problem, but I can't find out why it occures and what I did wrong even after I read error message and tried to find this sort of problem here

So the main goal is to add a book object into library array. No problems whit states, at least now, the should work correctly (console.log shows that everything's OK), exports and imports are correct in all files, I even have snippets in HiddenPanel.tsx file to use Library methods from Library.ts

Error: TypeError: Cannot read property 'push' of undefined Function.push../src/Library.ts.Library.addBook src/Library.ts:36

Line 36:

Library.library.push(book)

Quick problem description: some problem with types which I can't figure out. Occures after pressing ADD (which calls push() from method in Library.class)

Files: 1. HiddenPanel.tsx 2. Library.ts

I have a Book class with constructor (Library.ts)

class Book {
    constructor(public author: string, public title: string, public pages: string, public rating: number) {
        title = title
        author = author
        pages = pages
        rating = rating
    }     
}

Book constructor call-method is located in Library class (Library.ts)

class Library {
    static library: Array<object>

    library = [
        {
        author: 'Johann Fjord Kallenberg',
        title: 'Norvegian dragonslayers',
        pages: '443',
        rating: 4
        }, {
        author: 'Dungo McCallahey',
        title: 'Irish Golden Era',
        pages: '318',
        rating: 3
        }, {
        author: 'John Doe Mouse',
        title: 'Preparing to fight a Wolfgod',
        pages: '714',
        rating: 4
        }
    ]



public static addBook = (title: string, author: string, pages: string, rating: number) => {

        let book = new Book(title, author, pages, rating)
        Library.library.push(book)
        console.log(Library.library)
    }
}

Constructor is being called from HiddenPanel.tsx

class HiddenPanel extends React.Component<Props, State> {
    constructor(props: Props) {
        super(props)
        this.state = {
            author: '',
            title: '',
            pages: '',
            rating: 0,
            value: '',
        }
    }

    ...some private methods here...

    private handleClick = () => {
        Library.addBook(this.state.author, this.state.title, this.state.pages, this.state.rating)
    }
    render() {
        return(
            <div className="add-book-section">
                ...some stuff here... 
                <div onClick={this.handleClick} className="submit">ADD</div>

                </div>
        )
    }
}

Upvotes: 1

Views: 1027

Answers (2)

bloo
bloo

Reputation: 1560

Try defining your class like this..

class Library {
  static library = [
        {
        author: 'Johann Fjord Kallenberg',
        title: 'Norvegian dragonslayers',
        pages: '443',
        rating: 4
        }, {
        author: 'Dungo McCallahey',
        title: 'Irish Golden Era',
        pages: '318',
        rating: 3
        }, {
        author: 'John Doe Mouse',
        title: 'Preparing to fight a Wolfgod',
        pages: '714',
        rating: 4
        }
    ];
}

Upvotes: 1

Vivek Doshi
Vivek Doshi

Reputation: 58573

Issue :

If you read the comments and run the below snippet, that will clear the reason behind the issue.

class Library {
    static library: Array<object> // <-- Declared but not initialized
    
    // ---- this is not static property, this will create a property for class
    library = [ 
        {
        author: 'Johann Fjord Kallenberg',
        title: 'Norvegian dragonslayers',
        pages: '443',
        rating: 4
        }, {
        author: 'Dungo McCallahey',
        title: 'Irish Golden Era',
        pages: '318',
        rating: 3
        }, {
        author: 'John Doe Mouse',
        title: 'Preparing to fight a Wolfgod',
        pages: '714',
        rating: 4
        }
    ]
}

console.log( 'Static Property' , Library.library);

const libObj = new Library();
console.log( 'Instance Property' , libObj.library);

Solution :

You can initialized it with values directly :

class Library {
    static library: Array<object> = [
        {
        author: 'Johann Fjord Kallenberg',
        title: 'Norvegian dragonslayers',
        pages: '443',
        rating: 4
        }, {
        author: 'Dungo McCallahey',
        title: 'Irish Golden Era',
        pages: '318',
        rating: 3
        }, {
        author: 'John Doe Mouse',
        title: 'Preparing to fight a Wolfgod',
        pages: '714',
        rating: 4
        }
    ]
}

console.log( 'Static Property' , Library.library);

Upvotes: 1

Related Questions