问题
I'm building this exercise which involves the user filling out a form, and the info from the form is pushed into a firebase database and it produces a card which contains the info.
There are basically three functions: addBookToLibrary()
which takes the info from the form after the user hits the submit
button and puts it into firebase, render()
which draws the card with the info on it, and Book
which creates the object from the data entered into the form.
I decided to add retrievefromDatabase()
which would pull from the firebase database every time the page is loaded, and that's where I'm running into trouble.
I have one code that works, but it's a little complicated because it basically replicates render()
and makes two calls on firebase. A firebase pro here at StackOverflow suggested a new retrievefromDatabase()
and it's a lot cleaner and only makes one call but it causes the card to show all fields as "undefined."
I poked around by inserting "console.log" and each part results in what one might expect: newPostKey
is recognized, and so is oldBook
and so is archiveBook
.
Can someone wiser than me take a look and help me understand what the issue is?
let newPostKey;
let titlesnap;
let fnamesnap;
let lnamesnap;
let pubsnap;
let contribsnap;
function Book(title, fname, lname, pubDate, contrib, own) {
this.title = title;
this.fname = fname;
this.lname = lname;
this.pubDate = pubDate;
this.contrib = contrib;
this.own = own;
};
// better but not working:
// function retrievefromDatabase() {
// firebase.database().ref("Book").once("value", (book) => {
// book.forEach((snapshot) => {
// newPostKey = snapshot.key;
// console.log(newPostKey)
// function oldBook(title, fname, lname, pubDate, contrib, own) {
// this.title = title;
// this.fname = fname;
// this.lname = lname;
// this.pubDate = pubDate;
// this.contrib = contrib;
// this.own = own;
// };
// console.log(oldBook)
// var archiveBook = new oldBook(snapshot.val().title,
// snapshot.val().fname,
// snapshot.val().lname,
// snapshot.val().pubDate,
// snapshot.val().contrib,
// snapshot.val().own);
// console.log(archiveBook);
// })
// render();
// })
// };
function retrievefromDatabase() {
firebase.database().ref("Book").once("value", gotData);
function gotData(Book) {
var books = Book.val();
var keys = Object.keys(books);
for (var i = 0; i < keys.length; i++) {
firebase.database().ref("Book/" + keys[i]).once("value", function(snapshot) {
titlesnap = snapshot.val().title;
fnamesnap = snapshot.val().fname;
lnamesnap = snapshot.val().lname;
pubsnap = snapshot.val().pubDate;
contribsnap = snapshot.val().contrib;
newPostKey = snapshot.key;
const bookContainer = document.createElement("div");
bookContainer.classList.add("book-container");
const newVolume = document.createElement("div");
newVolume.classList.add("volume");
bookContainer.appendChild(newVolume);
bookContainer.setAttribute('id', `${newPostKey}`);
const frontCover = document.createElement("div");
newVolume.appendChild(frontCover);
frontCover.style.setProperty("background-color", getRandomColor());
frontCover.innerHTML = "<br /><br />"
+ "<b>" + titlesnap + "</b>" + "<br /><br />"
+ fnamesnap + " "
+ lnamesnap + "<br /><br />"
+ "Published: " + pubsnap + "<br />"
+ "Added by: <br />" + contribsnap + "<br />";
const checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.id = "checkbox";
if (snapshot.val().own == true) {
checkbox.checked = true;
}
else {
checkbox.checked = false;
};
checkbox.addEventListener("change", function() {
if (checkbox.checked === false) {
firebase.database().ref('Book/' + bookContainer.id + '/own').set(false);
}
else if (checkbox.checked === true) {
firebase.database().ref('Book/' + bookContainer.id + '/own').set(true);
}});
const label = document.createElement("label");
label.appendChild(document.createTextNode(" I own a copy"));
const newgraf = document.createElement("p")
frontCover.appendChild(checkbox);
frontCover.appendChild(label);
frontCover.appendChild(newgraf);
const removeButton = document.createElement('button')
frontCover.appendChild(removeButton);
removeButton.textContent = 'Remove';
removeButton.addEventListener("click", function(event){
firebase.database().ref('Book/').child(bookContainer.id).remove()
bookContainer.remove();
})
libraryContainer.insertAdjacentElement('afterbegin',bookContainer);
});
};
};
};
retrievefromDatabase();
const submitButton = document.querySelector(".submitButton")
submitButton.addEventListener("click", e => {
// the prevents the field from clearing on submit
e.preventDefault();
addBookToLibrary();
})
function addBookToLibrary() {
let title = document.querySelector("#title").value;
let fname = document.querySelector("#fname").value;
let lname = document.querySelector("#lname").value;
let pubDate = document.querySelector("#pubDate").value;
let contrib = document.querySelector("#contrib").value;
let own = document.querySelector("#own").checked;
var addBook = new Book(title, fname, lname, pubDate, contrib, own);
// I could just put document.querySelector values into var addBook but this is clearer
newPostKey = firebase.database().ref().child('Book').push().key;
firebase.database().ref().child('Book').child(newPostKey).set(addBook);
render();
document.querySelector("#title").value = "";
document.querySelector("#fname").value = "";
document.querySelector("#lname").value = "";
document.querySelector("#pubDate").value = "";
document.querySelector("#contrib").value = "";
document.querySelector("#own").checked = false;
// I can also shorten this with form.reset()
// https://discord.com/channels/505093832157691914/690590001486102589/736653879684628491
};
function render() {
const bookContainer = document.createElement("div");
bookContainer.classList.add("book-container");
const newVolume = document.createElement("div");
newVolume.classList.add("volume");
bookContainer.appendChild(newVolume);
bookContainer.setAttribute('id', `${newPostKey}`);
const frontCover = document.createElement("div");
newVolume.appendChild(frontCover);
frontCover.style.setProperty("background-color", getRandomColor());
let TitleRef = firebase.database().ref('Book/' + newPostKey + '/title');
TitleRef.once('value', function(snapshot) {
titlesnap = snapshot.val();
});
// why is this reversed? variable precedes
let FnameRef = firebase.database().ref('Book/' + newPostKey + '/fname');
FnameRef.once('value', function(snapshot) {
fnamesnap = snapshot.val();
});
let LnameRef = firebase.database().ref('Book/' + newPostKey + '/lname');
LnameRef.once('value', function(snapshot) {
lnamesnap = snapshot.val();
});
let pubRef = firebase.database().ref('Book/' + newPostKey + '/pubDate');
pubRef.once('value', function(snapshot) {
pubsnap = snapshot.val();
});
let contribRef = firebase.database().ref('Book/' + newPostKey + '/contrib');
contribRef.once('value', function(snapshot) {
contribsnap = snapshot.val();
});
frontCover.innerHTML = "<br /><br />"
+ "<b>" + titlesnap + "</b>" + "<br /><br />"
+ fnamesnap + " "
+ lnamesnap + "<br /><br />"
+ "Published: " + pubsnap + "<br />"
+ "Added by: <br />" + contribsnap + "<br />";
// reads checkbox form, adds it to the rendered volume and interprets value given
const checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.id = "checkbox";
if (document.getElementById("own").checked == true) {
checkbox.checked = true;
}
else if (document.getElementById("own").checked == true) {
checkbox.checked = false;
};
checkbox.addEventListener("change", function() {
if (checkbox.checked === false) {
firebase.database().ref('Book/' + bookContainer.id + '/own').set(false);
}
else if (checkbox.checked === true) {
firebase.database().ref('Book/' + bookContainer.id + '/own').set(true);
}
});
const label = document.createElement("label");
label.appendChild(document.createTextNode(" I own a copy"));
const newgraf = document.createElement("p")
frontCover.appendChild(checkbox);
frontCover.appendChild(label);
frontCover.appendChild(newgraf);
const removeButton = document.createElement('button')
frontCover.appendChild(removeButton);
removeButton.textContent = 'Remove';
removeButton.addEventListener("click", function(event){
firebase.database().ref('Book/').child(bookContainer.id).remove()
bookContainer.remove();
})
libraryContainer.insertAdjacentElement('afterbegin',bookContainer);
};
function getRandomColor() {
color = "hsl(" + Math.random() * 360 + ", 100%, 20%)";
return color;
}
if you want to see it in action, it's here: https://library-firebase.acchang.repl.co/
来源:https://stackoverflow.com/questions/63321366/why-am-i-getting-undefined-when-i-try-to-retrieve-this-array-of-objects-from-f