0

I am trying to create a DataAccess layer for handling data access with firebase. Inside the closure, I can see data variable get 3 items, but once it gets out of the closure and go to return statement, it becomes nil!

static let ref = Database.database()

static func GetGames(completion : @escaping ([String]) ->()){
    ref.reference(withPath: "games").observe(.value, with: { (snapshot) in
        guard let data = snapshot.value as? [String] else { return }
        completion(data)
    })
    { (error) in
        print("failed to fitch data",error)

    }
}

and her is my call

DataAccess.GetGames { (items) in
    self.games = items
}
pacification
  • 5,838
  • 4
  • 29
  • 51
Dot Freelancer
  • 4,083
  • 3
  • 28
  • 50
  • 2
    The closure executes asynchronously after the network operation completes, which is after the `GetGames` function returns, so data is `nil` *before* the closure executes and that is what your function returns. You cannot `return` data retrieved asynchronously. You need to pass a closure to `GetGames` (which should be `getGames` by convention) and invoke the passed closure from the `observe` closure. – Paulw11 Sep 07 '17 at 12:27
  • @Paulw11 one second, I am testing that – Dot Freelancer Sep 07 '17 at 12:30
  • @Paulw11 samething, it becomes nil https://www.dropbox.com/s/uvxwkcrmfhk2ixr/Screenshot%202017-09-07%2015.33.23.png?dl=0 – Dot Freelancer Sep 07 '17 at 12:34
  • and here's my call DataAccess.GetGames { (items) in self.games = items } – Dot Freelancer Sep 07 '17 at 12:34
  • @Paulw11 i updated the code – Dot Freelancer Sep 07 '17 at 12:38
  • 1
    It's still asynchronous. Move your print. `DataAccess.GetGames({ (items) in self.games = items; print(self.games) })`, not `DataAccess.GetGames({ (items) in self.games = items }) print(self.games)`. – jscs Sep 07 '17 at 12:51
  • @JoshCaswell thanks, I now understand the trick – Dot Freelancer Sep 07 '17 at 12:55

0 Answers0