Sending string from JSON data to variable outside of the function












0















I am attempting to take a string from JSON data and set it to a variable. My problem is that the variable shows as empty. I am using JSONDecoder to retrieve the JSON data and setting the string to a variable outside of the function. I then want to use that variable inside of another function



When I print the variable it still shows up as blank even after the function has loaded. Within the function the string appears correctly.



Code:



var filmTitle = ""

override func viewDidLoad() {
super.viewDidLoad()


loadFilms()
print(self.filmTitle) //Prints as an empty string

}

func loadFilms() {

let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/(id)?api_key=(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )

let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)

let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly

}
}
})


task.resume()

}


What am I missing to correctly set the string to the variable?










share|improve this question

























  • Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

    – rmaddy
    Nov 24 '18 at 1:42











  • How can I fix this since I need to use the data for another func.

    – JSharpp
    Nov 24 '18 at 1:43











  • I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

    – JSharpp
    Nov 24 '18 at 3:23
















0















I am attempting to take a string from JSON data and set it to a variable. My problem is that the variable shows as empty. I am using JSONDecoder to retrieve the JSON data and setting the string to a variable outside of the function. I then want to use that variable inside of another function



When I print the variable it still shows up as blank even after the function has loaded. Within the function the string appears correctly.



Code:



var filmTitle = ""

override func viewDidLoad() {
super.viewDidLoad()


loadFilms()
print(self.filmTitle) //Prints as an empty string

}

func loadFilms() {

let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/(id)?api_key=(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )

let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)

let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly

}
}
})


task.resume()

}


What am I missing to correctly set the string to the variable?










share|improve this question

























  • Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

    – rmaddy
    Nov 24 '18 at 1:42











  • How can I fix this since I need to use the data for another func.

    – JSharpp
    Nov 24 '18 at 1:43











  • I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

    – JSharpp
    Nov 24 '18 at 3:23














0












0








0








I am attempting to take a string from JSON data and set it to a variable. My problem is that the variable shows as empty. I am using JSONDecoder to retrieve the JSON data and setting the string to a variable outside of the function. I then want to use that variable inside of another function



When I print the variable it still shows up as blank even after the function has loaded. Within the function the string appears correctly.



Code:



var filmTitle = ""

override func viewDidLoad() {
super.viewDidLoad()


loadFilms()
print(self.filmTitle) //Prints as an empty string

}

func loadFilms() {

let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/(id)?api_key=(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )

let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)

let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly

}
}
})


task.resume()

}


What am I missing to correctly set the string to the variable?










share|improve this question
















I am attempting to take a string from JSON data and set it to a variable. My problem is that the variable shows as empty. I am using JSONDecoder to retrieve the JSON data and setting the string to a variable outside of the function. I then want to use that variable inside of another function



When I print the variable it still shows up as blank even after the function has loaded. Within the function the string appears correctly.



Code:



var filmTitle = ""

override func viewDidLoad() {
super.viewDidLoad()


loadFilms()
print(self.filmTitle) //Prints as an empty string

}

func loadFilms() {

let id = filmId
let apiKey = "97a0d64910120cbeae9df9cb675ad235"
let url = URL(string: "https://api.themoviedb.org/3/movie/(id)?api_key=(apiKey)&language=en-US")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )

let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)

let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try! JSONDecoder().decode(Details.self, from: data)
self.filmTitle = details.title
print(self.filmTitle) //string prints correctly

}
}
})


task.resume()

}


What am I missing to correctly set the string to the variable?







ios swift api jsondecoder






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 3:18







JSharpp

















asked Nov 24 '18 at 1:40









JSharppJSharpp

166113




166113













  • Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

    – rmaddy
    Nov 24 '18 at 1:42











  • How can I fix this since I need to use the data for another func.

    – JSharpp
    Nov 24 '18 at 1:43











  • I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

    – JSharpp
    Nov 24 '18 at 3:23



















  • Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

    – rmaddy
    Nov 24 '18 at 1:42











  • How can I fix this since I need to use the data for another func.

    – JSharpp
    Nov 24 '18 at 1:43











  • I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

    – JSharpp
    Nov 24 '18 at 3:23

















Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

– rmaddy
Nov 24 '18 at 1:42





Your code is fine. It's just that the data is loaded asynchronously so the print in viewDidLoad is called long before the data is loaded.

– rmaddy
Nov 24 '18 at 1:42













How can I fix this since I need to use the data for another func.

– JSharpp
Nov 24 '18 at 1:43





How can I fix this since I need to use the data for another func.

– JSharpp
Nov 24 '18 at 1:43













I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

– JSharpp
Nov 24 '18 at 3:23





I updated the question to declare that I plan to use the variable inside of another function. The new function is also decoding JSON data. I first need the filmTitle in order to run the other func.

– JSharpp
Nov 24 '18 at 3:23












3 Answers
3






active

oldest

votes


















0














Loading data from the internet is an asynchronous method. The print statement is being called before loadFilms() has completed.



Use a callback to get the data after it has completed.



func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
//...

let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
do { let details = try JSONDecoder().decode(Details.self, from: data)
completion(details, nil)


} catch {
completion(nil, error)
}
})

}


At the call site:



override func viewDidLoad() { 

loadFilms { details, error in

if error { //* Handle Error */ }

self.filmTitle = details.title
print(filmTitle)

}

}





share|improve this answer


























  • By at the call site do you mean where I run the func? Being viewDidLoad from my code.

    – JSharpp
    Nov 24 '18 at 2:45











  • @JSharpp Yes, from wherever you're running the method from.

    – SirCJ
    Nov 24 '18 at 2:49



















0














Web request are asynchronous and from the CP's perspective, take a long time to complete. When you call this:



override func viewDidLoad() {
super.viewDidLoad()

loadFilms()
print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
}


It's better to set a property observer on filmTitle:



var filmTitle: String? = nil {
didSet {
print(filmTitle)

Dispatch.main.async {
// update your GUI
}
}
}





share|improve this answer































    0














    The solution to this problem was to reload the collection view that the array was being sent to within the decoder function after the data was set to the array.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454471%2fsending-string-from-json-data-to-variable-outside-of-the-function%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      Loading data from the internet is an asynchronous method. The print statement is being called before loadFilms() has completed.



      Use a callback to get the data after it has completed.



      func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
      //...

      let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
      if let data = dataOrNil {
      do { let details = try JSONDecoder().decode(Details.self, from: data)
      completion(details, nil)


      } catch {
      completion(nil, error)
      }
      })

      }


      At the call site:



      override func viewDidLoad() { 

      loadFilms { details, error in

      if error { //* Handle Error */ }

      self.filmTitle = details.title
      print(filmTitle)

      }

      }





      share|improve this answer


























      • By at the call site do you mean where I run the func? Being viewDidLoad from my code.

        – JSharpp
        Nov 24 '18 at 2:45











      • @JSharpp Yes, from wherever you're running the method from.

        – SirCJ
        Nov 24 '18 at 2:49
















      0














      Loading data from the internet is an asynchronous method. The print statement is being called before loadFilms() has completed.



      Use a callback to get the data after it has completed.



      func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
      //...

      let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
      if let data = dataOrNil {
      do { let details = try JSONDecoder().decode(Details.self, from: data)
      completion(details, nil)


      } catch {
      completion(nil, error)
      }
      })

      }


      At the call site:



      override func viewDidLoad() { 

      loadFilms { details, error in

      if error { //* Handle Error */ }

      self.filmTitle = details.title
      print(filmTitle)

      }

      }





      share|improve this answer


























      • By at the call site do you mean where I run the func? Being viewDidLoad from my code.

        – JSharpp
        Nov 24 '18 at 2:45











      • @JSharpp Yes, from wherever you're running the method from.

        – SirCJ
        Nov 24 '18 at 2:49














      0












      0








      0







      Loading data from the internet is an asynchronous method. The print statement is being called before loadFilms() has completed.



      Use a callback to get the data after it has completed.



      func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
      //...

      let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
      if let data = dataOrNil {
      do { let details = try JSONDecoder().decode(Details.self, from: data)
      completion(details, nil)


      } catch {
      completion(nil, error)
      }
      })

      }


      At the call site:



      override func viewDidLoad() { 

      loadFilms { details, error in

      if error { //* Handle Error */ }

      self.filmTitle = details.title
      print(filmTitle)

      }

      }





      share|improve this answer















      Loading data from the internet is an asynchronous method. The print statement is being called before loadFilms() has completed.



      Use a callback to get the data after it has completed.



      func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
      //...

      let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
      if let data = dataOrNil {
      do { let details = try JSONDecoder().decode(Details.self, from: data)
      completion(details, nil)


      } catch {
      completion(nil, error)
      }
      })

      }


      At the call site:



      override func viewDidLoad() { 

      loadFilms { details, error in

      if error { //* Handle Error */ }

      self.filmTitle = details.title
      print(filmTitle)

      }

      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 24 '18 at 2:53

























      answered Nov 24 '18 at 1:50









      SirCJSirCJ

      157210




      157210













      • By at the call site do you mean where I run the func? Being viewDidLoad from my code.

        – JSharpp
        Nov 24 '18 at 2:45











      • @JSharpp Yes, from wherever you're running the method from.

        – SirCJ
        Nov 24 '18 at 2:49



















      • By at the call site do you mean where I run the func? Being viewDidLoad from my code.

        – JSharpp
        Nov 24 '18 at 2:45











      • @JSharpp Yes, from wherever you're running the method from.

        – SirCJ
        Nov 24 '18 at 2:49

















      By at the call site do you mean where I run the func? Being viewDidLoad from my code.

      – JSharpp
      Nov 24 '18 at 2:45





      By at the call site do you mean where I run the func? Being viewDidLoad from my code.

      – JSharpp
      Nov 24 '18 at 2:45













      @JSharpp Yes, from wherever you're running the method from.

      – SirCJ
      Nov 24 '18 at 2:49





      @JSharpp Yes, from wherever you're running the method from.

      – SirCJ
      Nov 24 '18 at 2:49













      0














      Web request are asynchronous and from the CP's perspective, take a long time to complete. When you call this:



      override func viewDidLoad() {
      super.viewDidLoad()

      loadFilms()
      print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
      }


      It's better to set a property observer on filmTitle:



      var filmTitle: String? = nil {
      didSet {
      print(filmTitle)

      Dispatch.main.async {
      // update your GUI
      }
      }
      }





      share|improve this answer




























        0














        Web request are asynchronous and from the CP's perspective, take a long time to complete. When you call this:



        override func viewDidLoad() {
        super.viewDidLoad()

        loadFilms()
        print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
        }


        It's better to set a property observer on filmTitle:



        var filmTitle: String? = nil {
        didSet {
        print(filmTitle)

        Dispatch.main.async {
        // update your GUI
        }
        }
        }





        share|improve this answer


























          0












          0








          0







          Web request are asynchronous and from the CP's perspective, take a long time to complete. When you call this:



          override func viewDidLoad() {
          super.viewDidLoad()

          loadFilms()
          print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
          }


          It's better to set a property observer on filmTitle:



          var filmTitle: String? = nil {
          didSet {
          print(filmTitle)

          Dispatch.main.async {
          // update your GUI
          }
          }
          }





          share|improve this answer













          Web request are asynchronous and from the CP's perspective, take a long time to complete. When you call this:



          override func viewDidLoad() {
          super.viewDidLoad()

          loadFilms()
          print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
          }


          It's better to set a property observer on filmTitle:



          var filmTitle: String? = nil {
          didSet {
          print(filmTitle)

          Dispatch.main.async {
          // update your GUI
          }
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 24 '18 at 3:16









          Code DifferentCode Different

          46.8k774107




          46.8k774107























              0














              The solution to this problem was to reload the collection view that the array was being sent to within the decoder function after the data was set to the array.






              share|improve this answer




























                0














                The solution to this problem was to reload the collection view that the array was being sent to within the decoder function after the data was set to the array.






                share|improve this answer


























                  0












                  0








                  0







                  The solution to this problem was to reload the collection view that the array was being sent to within the decoder function after the data was set to the array.






                  share|improve this answer













                  The solution to this problem was to reload the collection view that the array was being sent to within the decoder function after the data was set to the array.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 28 '18 at 3:08









                  JSharppJSharpp

                  166113




                  166113






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454471%2fsending-string-from-json-data-to-variable-outside-of-the-function%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                      Calculate evaluation metrics using cross_val_predict sklearn

                      Insert data from modal to MySQL (multiple modal on website)