Search code examples
swiftfirebasefirebase-realtime-databaselet

Getting a let value outside a function


Hello I'm new at swift programming and i want to get label value from loadData() to use use for my path (reference) to my database on dbRef!.child(place+"/placeLabel"). What I mean?! I read data that are on "Dio Con Dio" node. That happens because the value place is let place = "Dio Con Dio". So, my application doesn't load data from "Paradosiako - Panorama" node. I want to load everything from database and i thought that if i could make place value to change to the next node, it could read all the data.

    import UIKit
    import FirebaseDatabase

    class PlacesTableViewController: UITableViewController {

        //MARK: Properties
        @IBOutlet weak var placesTableView: UITableView!

        //database reference
        var dbRef:FIRDatabaseReference?

        var places = [Places]()

        private var loadedLabels = [String: String]()
        private var loadedRatings = [String: Int]()

        //handler
        var handle:FIRDatabaseHandle?

        override func viewDidLoad() {
            super.viewDidLoad()

            dbRef = FIRDatabase.database().reference()

            // Loads data to cell.
            loadData()
        }

                private func loadData() {

                let place = "Dio Con Dio"

                dbRef!.child(place+"/placeLabel").observe(.childAdded, with: {
                    (snapshot) in
                    let label = snapshot.value as! String
                    self.updatePlace(snapshot.key, label: label)
                })
                dbRef!.child(place+"/rating").observe(.childAdded, with: {
                    (snapshot) in
                    let rating = snapshot.value as! Int
                    self.updatePlace(snapshot.key, rating: rating)
                })


            }

            private func updatePlace(_ key: String, label: String? = nil, rating: Int? = nil) {
                if let label = label {
                    loadedLabels[key] = label
                }
                if let rating = rating {
                    loadedRatings[key] = rating
                }
                guard let label = loadedLabels[key], let rating = loadedRatings[key] else {
                    return
                }
                if let place = Places(name: label, rating: rating) {
                    places.append(place)
                    placesTableView.reloadData()
                }
            }
        }

**My Database**

(This question is a follow up from this one.)


Solution

  • For your new database schema, try this instead:

    private func loadData() {
        dbRef!.observe(.childAdded) {
        (placeSnapshot) in
            print("Adding place \(placeSnapshot.key)...")
    
            // Load each label on the "placeLabel" list. 
            let labels = placeSnapshot.childSnapshot(forPath: "placeLabel")
            for (key, label) in labels.value as! [String: String] {
                self.updatePlace(key, label: label)
            }
    
            // Load each rating in the "rating" list. 
            let ratings = placeSnapshot.childSnapshot(forPath: "rating")
            for (key, rating) in ratings.value as! [String: Int] {
                self.updatePlace(key, rating: rating)
            }
        }
    }
    

    The updatePlace function simply groups the label and rating properties, of a given place, that were separately loaded by loadData.

    Places removal. Of course, the above code won't handle place removal. To do so, you will need to listen for the childRemoved event as well.