0

I am trying to append values to an array inside a function and call that updated array in another function but it is not printing the new appended values.

I am using firebase and getting a snapshot of the database, sorting it, finding value of keys, and appending to hDates

var hDates:Array = [""]

getHistoryPGE() { hDates in
        print(hDates)
        self.hDates = [hDates]
    }

func getHistoryPGE(completion: @escaping (String)->()) {
    let userID = Auth.auth().currentUser?.uid
    let ref = Database.database().reference().child("users").child(userID!)

    ref.child("PostGameEval").observe(.value, with: { (snapshot) in
    if let dict = snapshot.value as? [String : [String: [String: Any]]] {

        let keys = Array(dict.keys)
        var num : Int = 7

        for i in 0..<keys.count {
            if let innerDict = dict[keys[i]] {
                let innerKeys = Array((innerDict).keys)
                let sortedInnerKeys = innerKeys.sorted(by: { $0 > $1} )
                while (sortedInnerKeys.count < num){
                    num -= 1
                }
                for j in 0..<num {
                    if let tempDict = innerDict[sortedInnerKeys[j]] {
                        print(tempDict["1abA"] as! String)
                    }
                }
            }

        }
    }})
}

func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
    let dateString = self.dateFormatter.string(from: date)
    if self.hDates.contains(dateString) {
        return 1
    }
    return 0
}
Will Mays
  • 102
  • 7
  • 1
    Please provide more context. Most probably you are doing some async (network) operations in the `getHistoryPGE` function and hence the issue, but without seeing more code, it is impossible to tell for sure what's wrong. – Dávid Pásztor Sep 18 '17 at 13:26
  • @DávidPásztor updated – Will Mays Sep 18 '17 at 13:29
  • 1
    David was right. You're not understanding the async aspect of the code. `.observe` is asynchronous and happens in the background. Have a look at this example for inspiration: https://stackoverflow.com/a/45999847/2227743 – Eric Aya Sep 18 '17 at 13:32
  • @Moritz so call the func from another function passing the array as parameter? – Will Mays Sep 18 '17 at 13:33
  • Take example from the link, just use whatever your object is (a date, apparently) instead of a string as in the example. This is called using a "callback", this is a very important concept. – Eric Aya Sep 18 '17 at 13:34
  • @WillMays it looks like you are using a 3rd party library for handling the calendar. Is `calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) ` called automatically for each date object that you want to display on your calendar or do you have to call it manually? – Dávid Pásztor Sep 18 '17 at 13:41
  • @DávidPásztor automatically – Will Mays Sep 18 '17 at 13:42
  • @Moritz it is successfully running but it is not resulting in this value: let dates = tempDict["Date"] as! String self.hDates.append(dates) – Will Mays Sep 18 '17 at 13:43
  • It looks like you still don't understand asynchronous programming. You will never be able to use a value from an async call the exact same way as you could use a normal synchronous return value. However, the other part of the issue is that you can' t just manually move the call for the `numberOfEventsFor date` function call inside the closure, since as you said it's being called automatically. Please explain in your question how and when is that function called by the system so that people can help you even if they never used `FSCalendar`. – Dávid Pásztor Sep 18 '17 at 14:32
  • @DávidPásztor i don't even need to call the calendar i just need the key tempDict["Date"] as! String saved to a dictionary i can call in any other function – Will Mays Sep 18 '17 at 14:35
  • As I've said, that won't work due to the async nature of the function. You have to ensure that all functions where you would use that piece of data is only called after the async function finished execution. – Dávid Pásztor Sep 18 '17 at 14:39
  • @DávidPásztor thanks for your help. I'll do more research – Will Mays Sep 18 '17 at 14:48
  • Another example: https://stackoverflow.com/a/31264556/2227743 The context is entirely different but the idea is exactly the same. You have to use a callback to "extract" the value from the asynchronous block and use it elsewhere eventually. – Eric Aya Sep 18 '17 at 14:53

0 Answers0