<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><p style="margin-right: 0px; margin-bottom: 15px; margin-left: 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px; margin-top: 0px !important;">Hi Diego,</p><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">We're working on an Angular-Rails project and have made some mistakes and learned a few things along the way. I cannot offer to do a paid and/or onsite gig, but I'd be happy to help with any specific questions you might have (thru LRUG, if it isn't terribly off-topic, or through email). </p><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">To start with, here are a bunch of pointers in no particular order. Apologies if you're already familiar with them. I'm also curious to hear everybody's thoughts on this and hopefully learn something in the process.</p><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">General</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Use Coffeescript.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Start with Egghead.io. Read AngularJS by Brad Green, Shyam Seshadri (<a href="http://shop.oreilly.com/product/0636920028055.do">http://shop.oreilly.com/product/0636920028055.do</a>). Spend a few hours and skim it cover-to-cover at least once. Angular documentation on the web is quite fragmented; a book is the best way to begin learning Angular.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">If you aren't familiar with Underscore.js already, go through it. Add it to the project as soon as you begin. You'll need it.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Drop <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">gem 'ng-rails-csrf'</code> into your Gemfile to make Angular AJAX requests play well with Rails CSRF protection.</p></li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">Directives</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Some material on the web might lead you to think that a deep understanding of Directives is crucial to ‘get’ Angular. But for a beginner, the important thing is to just have fun doing things the Angular way (it is loads of fun, let me assure you). The basic directives Angular provides (eg: ng-repeat and ng-show) can go a surprisingly long way. Worry about transclusion, $compile, $digest and other arcane incantations only after you get comfortable with the basics.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">One reason for you to write a directive is when you need to use existing widgets. A lot of popular widgets already have Angular wrappers. For example, we use the select2 wrapper <a href="https://github.com/angular-ui/ui-select2">https://github.com/angular-ui/ui-select2</a> for multi-select.</p><p style="margin: 15px 0px;">There is also AngularStrap (<a href="http://mgcrea.github.io/angular-strap/">http://mgcrea.github.io/angular-strap/</a>) with a bunch of nice components that wraps over Twitter Bootstrap. The v1 (<a href="http://mgcrea.github.io/angular-strap/1.0/">http://mgcrea.github.io/angular-strap/1.0/</a>) version has Datepicker and Timepicker which isn't available in the new version yet.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">You would hit a point when off-the-shelf directives won’t be enough and you'd want to do something that requires DOM manipulation. That would be a good time to start digging into Directives. You can also start exploring Directives when you start seeing patterns in your controllers that can be extracted out into reusable components.</p></li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">Serialization</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">We use ActiveModel::Serializer. It is a safe choice.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Pay close attention to what you include in each serializer. Here is the obvious thing: you can put a bunch of <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">has_many</code> in your User model, and if you keep doing that for other objects, a<code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">render json: User.all</code> will end up sending your entire db graph to the client. </p></li></ul><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">We implement a base serializer for most entities with some basic fields and no associations. When we need more data/associations, we sub-class them for that specific use case. Discourse follows a similar style - <a href="https://github.com/discourse/discourse/tree/master/app/serializers">https://github.com/discourse/discourse/tree/master/app/serializers</a></p><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;">Try not to do any decoration on the server side; it is tempting with all the view helper goodness Rails provides, but then you are splitting logic between client and server and it causes all sorts of headaches. You can use Angular filters as client-side helpers on some occasions. eg: {{ start_time | date }} prints out nicely formatted dates. </li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">Forms, validations and POJO form objects</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Angular gives you validation attributes like ng-required, ng-minlength, ng-maxlength etc. on all form INPUTs. For simple use cases, this is the best way to go. But for a complex form, we ended up building an ActiveModel-like POJO Form Object to hold validation information, and for doing some slight transformations on the data before submission. We bound this object to the scope and removed a lot of clutter from our controllers that had begun to get bloated. We have to see how this pans out in the long run; I can give code snippets if you wish.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">When I introduced Angular to our Rails project that was already under development, I tried to minimize the amount of change required by trying to keep form POSTs as they were.</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><input type='text' ng-model='post.title' name='post[title]'>
<input type='submit' />
</code></pre></li></ul><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">It worked for the most part, but we ran into some edge cases that wasted a lot of time. That was when I learned to let go and fully embrace the Angular way. We switched over to something like this:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><input type='text' ng-model='post.title' name='post[title]'>
<button ng-click='submitForm()'>
</code></pre><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">And the controller:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">angular.module('myApp').controller 'postCtrl', ['$log', '$scope', '$http', '$state', '$stateParams', '$window', 'flash', ($log, $scope, $http, $state, $stateParams, $window, flash) ->
  $scope.submitForm = ->
    $http.post(
      Routes.posts_path,
      $scope.post           # this is the ng-model hash we bound the input boxes to.
    ).success((data, status) ->
      $state.go("posts.show", {post_id: data.post.id})
    ).error((data, status) ->
      if data['message']
        flash.error = data['message']
      else
        flash.error = "Could not create Post. #{data}"
    )


# `flash`  is from <a href="https://github.com/wmluke/angular-flash">https://github.com/wmluke/angular-flash</a>. 

# $state.go is ui-router. <a href="https://github.com/angular-ui/ui-router">https://github.com/angular-ui/ui-router</a>. More on that later.

# we use JSRoutes to access Rails routes from JS. Quite useful. <a href="https://github.com/railsware/js-routes/">https://github.com/railsware/js-routes/</a>
</code></pre><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">The above code isn't ideal. You will be better off putting the <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">$http.post</code> inside an Angular service. This looks like a good post describing that: <a href="http://sravi-kiran.blogspot.in/2013/03/MovingAjaxCallsToACustomServiceInAngularJS.html">http://sravi-kiran.blogspot.in/2013/03/MovingAjaxCallsToACustomServiceInAngularJS.html</a>.</p><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">Rails+Angular</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Go all the way in. Don’t try to keep a mix of Angular and non-Angular pages. Except for Devise, all our pages are rendered client-side. We don't have to worry about SEO since this is an internal app.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Use ui-router <a href="https://github.com/angular-ui/ui-router">https://github.com/angular-ui/ui-router</a>, not the one that comes with Angular. The ui-router README could be confusing, but like most of Angular documentaiton, it becomes obvious in hindsight if you persevere.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">We keep everything together in the same Rails project. Here is a rough structure:</p><p style="margin: 15px 0px;">routes.rb:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">root ‘base#angular’
resources :posts, only: [:index]
</code></pre><p style="margin: 15px 0px;">app/views/base/angular.html.erb:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><div ng-app='myApp'>
  <div ui-view></div>
</div>
</code></pre><p style="margin: 15px 0px;">posts_controller.rb:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">  class PostsController < ApplicationController
    respond_to :json

    def index
      render json: Post.all, root: false
    end
  end
</code></pre><p style="margin: 15px 0px;">app/assets/javascripts/routes.coffee.erb:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">angular.module('myApp').run ($rootScope, $state, $stateParams) ->
  $rootScope.$state = $state
  $rootScope.$stateParams = $stateParams

angular.module('myApp').config ($stateProvider, $urlRouterProvider) ->

  # The default route
  $urlRouterProvider.when("", "/posts/list")

  $stateProvider
    .state("posts",
      url: "/posts"
      controller: "postsRootCtrl"
      template: '<div ui-view></div>'
      abstract: true
    ).state("posts.index",
      url: "/list"
      controller: "postsIndexCtrl"
      templateUrl: "<%= asset_path('posts/index.html.slim') %>"
      resolve:
        postsPromise: ($http) ->
          $http.get(Routes.posts_path())
    )
</code></pre><p style="margin: 15px 0px;">app/assets/javascripts/posts.js.coffee:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">angular.module('myApp').controller 'postsCtrl', ['postsPromise', '$log', '$scope', '$http', '$state', '$stateParams', '$window', (postsPromise, $log, $scope, $http, $state, $stateParams, $window) ->
  $scope.posts = postsPromise.data
</code></pre><p style="margin: 15px 0px;">app/assets/templates/index.html.slim</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">div ng-repeat='post in posts'
  h1
    | {{post.title}}
  p
    | {{post.body}}
</code></pre></li></ul><h2 style="margin: 20px 0px 10px; padding: 0px; -webkit-font-smoothing: antialiased; cursor: text; position: relative; font-size: 23px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); font-family: Helvetica, arial, sans-serif;">Quirks and bugs</h2><ul style="margin: 15px 0px; padding-left: 30px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;"><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">It is worth keeping in mind that in JS <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">{} == {}</code> is false, since comparisons are by object identity, not by object value. You can do explict comparison using <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Angular.equals</code> when you need it. But in some cases Angular does an implicit comparison, for which it doesn't use Angular.equals. For example, if you try loading a page with a bunch of pre-selected radio-buttons, if their values are JS Objects (Hash), Angular won't pre-select them since the comparison will fail. This is not an issue if your values are strings/numbers.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">JS treats the keys of all objects as strings.<code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">a={1: "Hello"}; _.each(a, (value, key) -> console.log(typeof key))</code>. If your server sends Hashes whose keys are numeric ids, they'll end up in JS with string ids.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">A quick and dirty way to inspect an Angular model is to drop this in your Angular view template:</p><pre style="margin-top: 15px; margin-bottom: 15px; background-color: rgb(248, 248, 248); border: 1px solid rgb(204, 204, 204); font-size: 12px; line-height: 19px; overflow: auto; padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;"><code style="margin: 0px; padding: 0px; border: none; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">pre
  | {{ post | json }}
</code></pre></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">There is also Batarang, a Chrome plugin which lets you inspect your scope interactively. But I've found it to causes my pages to misbehave in certain cases. I these days use angular-chrome-debug, (<a href="https://gist.github.com/mzgol/7893061">https://gist.github.com/mzgol/7893061</a>) which is quite light-weight. I load this script in my app in development env so that I don't have to go thru Chrome Snippets everytime.</p></li><li style="margin: 0px;"><p style="margin: 0px 0px 15px;">Angular has <code style="margin: 0px 2px; padding: 0px 5px; white-space: nowrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">Angular.copy</code> for deep copy when you need it - <a href="https://github.com/angular/angular.js/blob/master/src/Angular.js#L725">https://github.com/angular/angular.js/blob/master/src/Angular.js#L725</a>.</p></li></ul><p style="margin: 15px 0px; font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">Well, that's mostly it. Please keep in mind that the structure I described is working well for our app, which is not meant for public consumption. You might want to look at keeping your Angular and Rails project separately and utilize JS build tools like Bower, Yeoman and Grunt if your app needs that.</p><div><span style="font-family: Helvetica, arial, sans-serif; font-size: 13px; line-height: 22px;">I'm generally liking building rich UIs with Angular and wouldn't go back to building for the web without using data-binding. Awesome sauce.</span></div><div><br></div><div apple-content-edited="true">
<div style="color: rgb(0, 0, 0); font-family: Helvetica;  font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>--</div><div>Jasim A Basheer — Nilenso Software — <a href="http://nilenso.com" style="text-align: -webkit-auto;">http://nilenso.com</a></div><div><a href="http://twitter.com/jasim_ab">http://twitter.com/jasim_ab</a></div></div><div><br></div></div><br class="Apple-interchange-newline"><br></div>
<br><div><div>On 16-Jan-2014, at 6:20 am, Matthew Rudy Jacobs <<a href="mailto:matthewrudyjacobs@gmail.com">matthewrudyjacobs@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 15 January 2014 14:38, Matt Spendlove <span dir="ltr"><<a href="mailto:matt@cenatus.org" target="_blank">matt@cenatus.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><div><br></div><div>I’ve never used the service but these guys seem to be trying to solve your kind of request:</div><div><br></div><div><a href="https://www.airpair.com/" target="_blank">https://www.airpair.com</a></div>

</div></blockquote><div><br></div><div>Also check out CodeMentor, who do something similar.</div><div><a href="https://www.codementor.io/directory/angularjs">https://www.codementor.io/directory/angularjs</a> </div></div>
</div>
</div>
_______________________________________________<br>Chat mailing list<br><a href="mailto:Chat@lists.lrug.org">Chat@lists.lrug.org</a><br>http://lists.lrug.org/listinfo.cgi/chat-lrug.org<br></blockquote></div><br></body></html>