Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax error when attempting to do work in .then{} prior to executing next Promise function #176

Open
heloguy opened this issue Sep 13, 2021 · 1 comment

Comments

@heloguy
Copy link

heloguy commented Sep 13, 2021

getEventsFromDatabase(for: today)
      .then { data in
       // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

The above code works as advertised in the documentation.

getEventsFromDatabase(for: today)
      .then { data in
        self.progress.progress = 0.2 // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

In the first closure I add a block of code to update the UIProgressView.

Syntax error: Missing return in a closure expected to return 'Promise'

A look at the individual function differences:

1

private func getEventsFromDatabase(for date: Date) -> Promise<[NonCodableEvent]> {
    return Promise {
      return try DatabaseController.getEventsForDate(date: date, container: self.persistentContainer)
    }
  }

2

  private func getEventsFromNetwork(for date: Date, event: [NonCodableEvent]) -> Promise<Any> {
    if(event.count > 0) {
      return Promise(on: .global()) { () -> [NonCodableEvent] in
        return event
      }
    }
    
    return Promise(on: .global()) { () -> Any in
      let (data, response, error) = ServiceLayer().request(route: NavyRoute(squadron: Squadron.ht8, date: date))
      if let error = error {
        throw error
      }
      
      //TODO: Handle response code issues
      
      return data
    }
  }

In '1', I'm returning a "generic" promise on the .main thread.
In '2', I'm returning a Promise explicitly run on the .global thread.

Trying to wrap my head around why this might be causing issues, or if there's something else I'm missing.

@chuckhays
Copy link
Collaborator

I think the confusion may be from swift automatically returning the value of a single line block. Once you add a second line that no longer happens.

Starting with your first block:

getEventsFromDatabase(for: today)
      .then { data in
      // Then block 1
       // Diff
        self.getEventsFromNetwork(for: today, event: data)
      }
      .then { data in
      // Then block 2
        self.progress.progress = 0.5
        self.parsePDF(data)
      }
      .then { data in
      // Then block 3
        self.progress.progress = 0.5
        self.updateViewData(for: self.todayEvents, data: data)
      }

In then block 1, the Promise from the call to self.getEventsFromNetwork is returned. But in then block 2, the return type of the then block is Void. Same with block 3.

So block 2 will get the result data from self.getEventsFromNetwork, but block 3 will also get those same results because block 2 has no return value.

Once you add the second line in the first block, all of the blocks now get the initial result from getEventsFromDatabase.

First thing I would try is adding explicit return statements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants