Search code examples
combineobservableobjectobservedobject

ObservedObject only passes its default value; not its assigned value. Why?


Scenario: Attempting to broadcast a variable value via an ObservableObject.
Problem: I'm only getting the default value; not the assigned value.

Here's the origin.
Button #1 starts a function to get data.
Button #2 retrieves the ObservedObject's revised value

I removed some of the vestigial code to make the presentation simpler:

struct ContentView: View {
    @ObservedObject var networkManager = NetworkManager()

    let fontCustom = Font.custom("Noteworthy", size: 23.0)

    var body: some View {
        ZStack {
        // ...
        // ...
 HStack {
         Button(
              action: {
                  NetworkManager().getCalculatorIDs()
              },
              label: { 
                 Text("1")
              }
         )

        Button(
             action: {
                 self.calculator.calculate("2");
                 print(self.networkManager.calculationID)  // stop and check.                            
             },
             label: { Text("2") }
        )
// ...
// ...
}
}

So I tap Button #1 then tap Button #2 to check if the ObservedObject has the generated id value.

I'm expecting an alphanumeric id value in the print().

Instead, I got the original value:

Royal Turkey
(lldb) 

Here's the ObservableObject:

struct CalculationIdentifier: Decodable {
    let id: String
    let tokens: [String]
}

class NetworkManager: ObservableObject {
    @Published var calculationID = "Royal Turkey"
    @Published var isAlert = false
    @Published var name = "Ric Lee"

    let calculations = "https://calculator-frontend-challenge.herokuapp.com/Calculations"

    func getCalculatorIDs() {
        let urlRequest = URLRequest(url: URL(string: calculations)!)
        let configuration = URLSessionConfiguration.ephemeral

        let task = URLSession(configuration: configuration).dataTask(with: urlRequest) { data, _, error in

            DispatchQueue.main.async {
                do {
                    let result = try JSONDecoder().decode([CalculationIdentifier].self, from: data!)
                    if !result.isEmpty {
                        self.calculationID = (result[0] as CalculationIdentifier).id
                        print("Inside do{}. result = \(result)")
                        self.isAlert = true
                    } else {
                        print(#function, "Line:", #line, ": No Result")
                    }
                } catch {
                    print(error)
                }
            }
        }

        task.resume()
    }
}

BTW: Here's the local console output, the string value of 'id' should have been passed to the host as an ObservedObject value:

Inside do{}. result = [RicCalculator2.CalculationIdentifier(id: "d3dd3b1e-d9f6-4593-8c85-b8fd3d018383", tokens: [])]

So I do have a bona fide id value to send.

Why only the original value?
What am I missing?

...do I need to do a 'send' or something?


Solution

  • This

    A. @ObservedObject var networkManager = NetworkManager()

    and this

    B. NetworkManager().getCalculatorIDs()

    in your code are different objects, ie. you create one object as member, then other object on the stack, which does something, and then ask first object to return something - naturally if returns what it has on initialise.

    Probably you assumed in case B

    self.networkManager.getCalculatorIDs()