Reputation: 143
I have declared requestPostArray right at the beginning of the ViewController class. I'm trying to populate the requestPostArray from the database "Request Posts" and then populate the tableView from the requestPostArray. However when I print it's size it shows up to be 0. Any help would be appreciated.
Also, the entire else statement below is inside another closure.
else {
ref.child("Request Posts").observe(.value, with: { (snapshot) in
let count = Int(snapshot.childrenCount)
// Request Post database is empty
if count == 0 {
cell.nameLabel.text = "No requests so far."
cell.userNameLabel.isHidden = true
cell.numberOfRequestsLabel.isHidden = true
}
// Request Post data is populated
else {
var requestPostArray: [RequestPost]? = []
self.ref.child("Request Posts").observe(.value, with: { (snapshot) in
if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {
for child in result {
let post = RequestPost(snapshot: child)
requestPostArray?.append(post)
}
}
else {
print("No Result")
}
})
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")
cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
}
})
}
Upvotes: 0
Views: 378
Reputation: 1056
this is what should happens because observe function is asynchronous and the rest of your code is synchronous, in addition if you remove the optional unwrap from requestPostArray?
you will get a nil exception because the async task needs time to get executed so the compiler will execute the snyc task before it.
basically what you have to do is the following
else {
ref.child("Request Posts").observe(.value, with: { (snapshot) in
let count = Int(snapshot.childrenCount)
// Request Post database is empty
if count == 0 {
cell.nameLabel.text = "No requests so far."
cell.userNameLabel.isHidden = true
cell.numberOfRequestsLabel.isHidden = true
}
// Request Post data is populated
else {
var requestPostArray: [RequestPost]? = []
self.ref.child("Request Posts").observe(.value, with: { (snapshot) in
if let result = snapshot.children.allObjects as? [FIRDataSnapshot] {
for child in result {
let post = RequestPost(snapshot: child)
requestPostArray?.append(post)
}
}
else {
print("No Result")
}
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")
cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
})
}
})
}
another advice think about using singleton so you can gain the reuse of your object and you will not invoke the database several time at the same method like you are doing now.
Upvotes: 1
Reputation: 17958
observe
blocks are asynchronous. You're reading requestPostArray
before it has been modified by your requestPostArray?.append(post)
line.
Without more context it's hard to know how you want to be populating values on this cell
object but if you need "Request Posts" then you have to wait until you've been able to obtain them.
Upvotes: 3