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

Refresh view after async response #35

Open
newPrimitives opened this issue Jul 20, 2016 · 4 comments
Open

Refresh view after async response #35

newPrimitives opened this issue Jul 20, 2016 · 4 comments
Labels

Comments

@newPrimitives
Copy link

When I render a view and call some async API how do I update that view? I could not find any reload/refresh methods in the docs. For example:

app.get("/home") { request in
    HomeController().fetchData { posts in  
       // Update view with response 
    }
    return HomeController.index("/home")
}
@ypopovych
Copy link
Member

Hi @newPrimitives, thanks for your question.

Swift Express has a Future based asynchronous APIs. You can return Future from your route callback, and then complete it at any time.

Something like this

import BrightFutures

app.get("/home") { (request:Request<AnyContent>) -> Future<Action<AnyContent>, AnyError> in
    // Creating promise
    let p = Promise<Action<AnyContent>, AnyError>()

    HomeController().fetchData { posts in
        //Completing promise with some result  
        p.success(Action<AnyContent>.render("home", context: ["posts":  posts])
    }

    //Returning future
    return p.future
}

@dileping
Copy link
Member

@newPrimitives @ypopovych

I can suggest a simpler and a more generic way of converting your callbacks based API to Futures.

Assuming you have something like this (correct me if I'm wrong):

class HomeController {
    static func fetchData(callback:(posts: [String])->Void) {
        callback(posts: ["post1", "post2"])
    }
}

add somewhere in your code following function that will convert it to a Future:

func futurify<Payload>(fun:((Payload)->Void)->Void) -> Future<Payload, AnyError> {
    let p = Promise<Payload, AnyError>()

    fun { payload in
        p.success(payload)
    }

    return p.future
}

With all above you can handle it as easy as:

app.get("/home") { (request:Request<AnyContent>) -> Future<Action<AnyContent>, AnyError> in
    return futurify(HomeController.fetchData).map { posts in
        Action.render("home", context: ["posts": posts])
    }
}

Let me know if this worked for you, please.

@newPrimitives
Copy link
Author

newPrimitives commented Jul 22, 2016

@dileping @ypopovych it works. I've implemented this in one of my tutorials which you can check here: http://nermin.tech/swift-on-servers-101-swift-express/
Also there's a gihtub repo with the code from the tutorial on my profile: https://github.com/newPrimitives/swift-express-demo
Feel free to suggest improvements.

@dileping
Copy link
Member

dileping commented Jul 22, 2016

@newPrimitives Hey, great article! Thanks ;)

There are a couple of things that actually usually work:

At the moment of writing this tutorial building application from Xcode will not work, so you have to do it manually through terminal

Which Xcode have you used and how were you making it work? It works for me...

One thing that you should take into consideration is that building and running Swift Express application after you’ve already built it on the same port will not trigger the update, because the port was in use. To solve this problem, you can chain terminal commands in the following order: kill all processes on the given port, build changes if any, run applicaiton on the same port. The terminal command will look like this:

Usually it works just by quitting swift-express run with Ctrl+C (or with stop if running from Xcode). Could you let me know more details?

Also I'm going to make a PR to your article's code. Just to make it better using async capabilities along with Futures.

Best,
Daniel

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

No branches or pull requests

3 participants