JS function needs to return an object

Hi,
I struggle to understand how to return something out of a function, in other words, how to make it available in the global scope.

Below function takes user input and places it into an object book. My question is, how do I update book (or return it) outside of my addBook() function?

let bookArray = [];
let book = {};
let addBookButton = document.querySelector(".js-addBook");

function addBook() {
    let title = document.querySelector(".js-title").value;
    let author = document.querySelector(".js-author").value;
    let pages = document.querySelector(".js-pages").value;

    book = {
        title: title,
        author: author,
        pages: pages
    }
}

What you’re looking for is probably this return book = {//your stuff here}

Also, I’m not 100% sure what you’re doing but maybe look into this code:

function addBook() {   
 let title = document.querySelector(".js-title").value;
    let author = document.querySelector(".js-author").value;
    let pages = document.querySelector(".js-pages").value;

    return  {
        title: title,
        author: author,
        pages: pages
    }
}

Then you can run book = addBook()


But I would look into functions, maybe at MDN first.

You aren’t trying to return something and putting it in global scope, you’re either trying to modify the global variable book

book.title = title
...

Or you’re modifying the global variable bookArray: create a book object as you are already and push it to bookArray in that case

This is still probably going to cause some issues for you because events are asynchronous, bit you aren’t at that point yet

I should’ve been clearer in my question. Sorry. What you said is exactly what I try to achieve.

function addBook() {
    let title = document.querySelector(".js-title").value;
    let author = document.querySelector(".js-author").value;
    let pages = document.querySelector(".js-pages").value;

    book = {
        title: title,
        author: author,
        pages: pages
    }
    
    bookArray.push(book);
    console.log(bookArray);
}

console.log() within addBook() returns exactly what I expect. But now, and I suspect I’m lacking knowledge here,

console.log(bookArray);

outside of addBook() returns an empty array. Obviously, because it’s been updated inside of the addBook()

So, how do I get addBook() to return whatever is in my book object?

Yes, that’s exactly it. But my problem is, that if I console.log(book) outside of addBook(), it returns an empty object.

Will have to do some reading, no doubt.

Can you include the html or share a codepen?

You can’t, that’s not how JavaScript (and non-blocking asynchronous programming in general) works. It’s not synchronous in terms of how the program is written top to bottom. You have an array of books. It’s empty. You have a function that fires when a click event happens on that button. You are then I think trying to console.log the array. The function fires, and sometime later the callback occurs and pushes a book to the array. But the console.log has already happened.

What are you trying to do with the book array? console.logging isn’t a real thing, and normally you would actually do the thing you’re trying to do in the callback.

You can also create an object that contains the collection, along with methods for adding books to it and a method to get the books or a book or whatever (either using a class or a closure or whatever). Then you create the object at start of your program, then do logic to add books, then you can use the get method to look at the object. ie you have an interface around a global object that lets you add to and inspect the books list. This is what Redux does, for example.

1 Like

ok, thanks for the help

You are confusing things with the code here. You have two event handlers attached to the same click event, one an inline one on the button and one in the JS. So for starters, remove the inline one, you don’t want that. The callback to addEventHandler should be the addBook function.

That’s it! So, if I understand you right, it should look like this now

// prevent form clearing inputs
document.querySelector(".js-form").addEventListener("click", function (event) {
    event.preventDefault();    
    event.addBook;
});

let bookArray = [];
let book = {};
let addBookButton = document.querySelector(".js-addBook");

function addBook() {
    let title = document.querySelector(".js-title").value;
    let author = document.querySelector(".js-author").value;
    let pages = document.querySelector(".js-pages").value;

    book = {
        title: title,
        author: author,
        pages: pages
    }
    
    bookArray.push(book);
}

After every click on the button, I add a new object book and push that into the bookArray array. Seems to work as expected now.

image

1 Like