Integrating Lift with large/complex js libraries

57 views
Skip to first unread message

khxela

unread,
Jul 8, 2013, 12:42:20 PM7/8/13
to lif...@googlegroups.com
Hey all,

I'm about to try writing my first major app in lift and I was curious about the "best approach" for integrating complex js libraries with some of the functionality in lift (like comet).  Just for an example, take a foursquare-like service that is heavily reliant on a js map library such as mapbox or leaflet.  One obvious use case is to be able to click on some place on the map and have a popover/modal with more information about the place, fetched via ajax.  Now for a regular form, the way to do this would be via a snippet with SHtml.ajaxXXX on the field, but something like mapbox will just have an onClick event or similar that you have to hook into.  Another (perhaps more frivolous, but I couldn't come up with a more practical one) case is to use lift's comet functionality to add extra places onto the map as they are added by users.

The approach I can immediately think of (that you can do with any web framework) is to establish appropriate resthelper endpoints to serve the data, for the first use case.  However I feel like that gives up some advantages that lift has built-in, like not having to expose your pkeys so openly, and even then it doesn't solve something like the second use case where you want to tie comet in.

I'm wondering if anyone who's used lift more heavily has any thoughts on this, or if this is a more specialized case than I imagine and it's better off just to use the usual api-with-heavy-frontend approach.

Antonio Salazar Cardozo

unread,
Jul 8, 2013, 2:26:43 PM7/8/13
to lif...@googlegroups.com
Comet is designed to invoke anything client-side. I've typically used comet to dispatch events on the document object, which are then listened to by various areas of the code and used to take actions like, in your case, adding points on the map. I've been using something vaguely like this:

  class OpenStudyEvent(event:String, data:JObject = JObject(List())) extends JsCmd {
    override val toJsCmd = {
      if (data.obj.length == 0)
        Call("openstudy.event", event).cmd.toJsCmd
      else
        Call("openstudy.event", event, data).cmd.toJsCmd
    }
  }

  class BasicOpenStudyEvent(event:String) extends JsCmd {
    import Serialization._

    implicit val formats = Serialization.formats(NoTypeHints)

    override val toJsCmd = {
      Call("openstudy.event", event, decompose(this)).cmd.toJsCmd
    }
  }

And passing that to partialUpdate.

As for the flip side, you can map arbitrary functions on the server and pass the ids down to the client to run ajax invocations. For example, there are areas of apps where you could pass down something like:

      SHtml.ajaxInvoke(() => {
        ShowEditMessageModal(event.id, messageInfo.subject, messageInfo.body)
      }).guid

The result of that is a String that you can then pass to a function that looks something like this on the client:

    liftAjaxCall = function(functionName, functionValue) {
      functionValue = functionValue || 'true';
      liftAjax.lift_ajaxHandler(functionName + '=' + functionValue, null, null, null);
    }

This particular approach is Diego's, btw. My approach in the past has been to send down the full JS expression that calls liftAjax.lift_ajaxHandler. 

You can also have other helpers like:

  def functionIdForStringField(fn:(String)=>Any) : String = {
    S.fmapFunc(S.SFuncHolder(string => fn(string)))((name:String) => name)
  }

This would let you invoke that server side function with a String. You can pair these with RestHelpers (just make sure the RestHelpers are attached using dispatch, not stateless dispatch) to combine the ease of REST with server-side function invocation and get the best of both worlds.

Hope that helps, feel free to ask any followups if you need any clarification on any of this.
Thanks,
Antonio

Diego Medina

unread,
Jul 8, 2013, 7:55:36 PM7/8/13
to Lift
Besides all the good feedback Antonio gave you, reading these may help too:


Thanks

  Diego


--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code
 
---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://fmpwizard.telegr.am

David Pollak

unread,
Jul 8, 2013, 8:00:02 PM7/8/13
to lif...@googlegroups.com

Please see http://blog.goodstuff.im/roundtrip_promises

A lot of the across address space stuff is handled with streaming promises.

Torsten Uhlmann

unread,
Jul 9, 2013, 1:44:51 AM7/9/13
to lif...@googlegroups.com
An example that uses Roundtrip Promises is here: https://github.com/tuhlmann/lift-3-demo

It doesn't implement Streaming Promises yet...

-- 
AGYNAMIX(R). Passionate Software.
Inh. Torsten Uhlmann | Buchenweg 5 | 09380 Thalheim
Phone:       +49 3721 273445
Fax:             +49 3721 273446
Web:           http://www.agynamix.de
Author of "Lift Web Applications How-To"
Reply all
Reply to author
Forward
0 new messages