0

Right now I have to call the function (calculatePortfolioGrossBalance) 3 times for the value to update, what am I doing wrong in the state logic?

In the code below, when I call in an init the function calculatePortfolioGrossBalance() it returns empty [], I have to call it 3 times for the value to update, However... if I print the values of getTokenBalancesModel in the line DispatchQueue.main.async { I can see the values are there, so how come in calculatePortfolioGrossBalance are not?

final class TokenBalancesClassAViewModel: ObservableObject {
    
    @Published var getTokenBalancesModel: [TokenBalancesItemsModel] = [TokenBalancesItemsModel]()
    @Published var portfolioGrossBalance: String = "0.0"
    
    
    func calculatePortfolioGrossBalance() {
        getTokenBalances()
        
        DispatchQueue.main.async {
            var totalBalance: Double = 0
            
            for item in self.getTokenBalancesModel {
                totalBalance += Double(item.quote!)
            }
            
            self.portfolioGrossBalance = String(format:"%.2f", totalBalance)
            print(self.portfolioGrossBalance)
        }
    }
    
    func getTokenBalances() {
        guard let url = URL(string: "someUrlHeidiGaveMe") else {
            print("Invalid URL")
            return
        }
        
        print("Calling getTokenBalances() ...")
        
        AF.request(url, method: .get).validate().responseData(completionHandler: { data in
            do {
                guard let data = data.data else {
                    print("Response Error:", data.error as Any)
                    return
                }
                
                let apiJsonData = try JSONDecoder().decode(TokenBalancesModel.self, from: data)
                DispatchQueue.main.async {
                    self.getTokenBalancesModel = apiJsonData.data.items
                }
            } catch {
                print("ERROR:", error)
            }
        })
    }
}

1 Answer 1

1

you need to read up on using asynchronous functions, how to set them up and how to use them. This is important. Try something like this (untested):

final class TokenBalancesClassAViewModel: ObservableObject {
    
    @Published var getTokenBalancesModel: [TokenBalancesItemsModel] = [TokenBalancesItemsModel]()
    @Published var portfolioGrossBalance: String = "0.0"

    func calculatePortfolioGrossBalance() {
        getTokenBalances() { isGood in
            if isGood {
                var totalBalance: Double = 0
                for item in self.getTokenBalancesModel {
                    totalBalance += Double(item.quote!)
                }
                self.portfolioGrossBalance = String(format:"%.2f", totalBalance)
                print(self.portfolioGrossBalance)
            }
        }
    }
    
    func getTokenBalances(completion: @escaping (Bool) -> Void) {
        guard let url = URL(string: "someUrlHeidiGaveMe") else {
            print("Invalid URL")
            completion(false)
            return
        }
        
        print("Calling getTokenBalances() ...")
        
        AF.request(url, method: .get).validate().responseData(completionHandler: { data in
            do {
                guard let data = data.data else {
                    print("Response Error:", data.error as Any)
                    completion(false)
                    return
                }
                
                let apiJsonData = try JSONDecoder().decode(TokenBalancesModel.self, from: data)
                DispatchQueue.main.async {
                    self.getTokenBalancesModel = apiJsonData.data.items
                    completion(true)
                }
            } catch {
                print("ERROR:", error)
                completion(false)
            }
        })
   
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

That worked, many thanks. I do recognize I still have lots of reading. Will look into it, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.