1
votes

I'm new to angularjs/clientjs and would like to consume a rails json api with angularjs. After some research I wrote the ff: code but when I visit http://localhost:3000/users I get plain json. Angularjs is not being called to render a view.

How can I render an angularjs view that formats and shows the data a rails json api returns?

rails/routes

app::Application.routes.draw do
  get 'main/index' => 'main#index'
  resources :users, defaults: {format: :json}
end

rails/users_controller.rb

def index
 @users = User.all
end

rails/main_controller.rb

def index
 # blank
end

rails/application layout

..
<html ng-app='gold'>
..
<div ng-view>
  <%= yield %>
</div>
..

app/assets/templates/main/index.html

app/assets/templates/users/index.html

app/assets/javascripts/main.js

var myApp = angular.module('gold', ['ngRoute', 'ngResource']);

myApp.config(function($routeProvider, $locationProvider, $httpProvider) {
    console.log("in router")
    $httpProvider.defaults.headers.common['X-CSRF-Token'] = 
    $('meta[name=csrf-token]').attr('content');
    $locationProvider.html5Mode(true);
    $routeProvider.
        when('/users', {
            templateUrl: '../assets/users/index.html',          
            controller: 'UsersController'
        }).when('/main/index', {
            templateUrl: '../assets/main/index.html',
            controller: 'MainController'
        }).otherwise({
            redirectTo: '/'
        });
});

app/assets/javascripts/services/UserService.js

myApp.factory('UserService', ['$resource', function($resource) {
console.log("in user service")
return $resource('/users/:id', {id: '@id'}, {
    index: { method: 'GET', isArray: true },
    create: { method: 'POST' },
    show: { method: 'GET' },
    update: { method: 'PUT', params: {id: '@id'} }
    //delete: { method: 'DELETE', params: {id: '@id'} }
});
}]);

app/assets/javascripts/controllers/UsersController.js

myApp.controller('UsersController', ['$scope', 'UserService', function($scope, UserService) {
 console.log("in user controller")
   $scope.users = UserService.query();
}]);
1
What is your question?Peter Brown
I edited it out accidentally. Still I thought it was obvious. Angularjs templates are not being called. Neither are rails templates. Just json.LightBox
You're specifying the default format to be json in your routes.rb for /users. If you don't want that to be the case, why is it there? If you want the default format to be HTML, just remove it. Otherwise, you should be able to add .html to the end of the URL.Peter Brown
I'm not sure I understand you. I would like the rails app to send json to the angularjs client. The angularjs client would then use the json data to render a angular html template. Is this how angular works? I'm new to this. I assumed I should not use rails templates at all but some tutorials have been using rails templates along with angular templates. Should I just delete the rails view directory?LightBox
I too have a similar issue. Is the above issue resolved ? Can any one help ?Rajasree Muraleedharan

1 Answers

0
votes

I think I know what you are trying, as I'm working on similar problem.

  1. Once Rails sends json, that is it. You can't ask it to render other html/erb and use it to interpret the json data.
    see this answer on How can we use rails routes with angularjs in a DRY way?

  2. To achieve both Rails + Angular routing at the same time (render Rails pages with URL, json data with ajax/api calls), I have setup a @view model contains Angular page url for the request + json data.

For a normal HTML request: default.html.erb translates the @view variable to .js using a "jsonService.js.erb", and render the angular page in @view.

For ajax/api calls: Setup routes using angular.config as you did for render page, and add resolve: fetchData(controller#action) to fetch the json data from Rails controllers and use it in the angular page.

respond_to do |format|
  format.json { @view }
  format.html { render 'layouts/default' }
end
<script id="jsonService"><%= render "layouts/json_service.js" %></script>
<div ng-include ="content.view.template"></div>

You can use what you got for angular.config. Just remember to use ng-href or ng-click for the links in json/api calls.

if you have dynamic routing in the angular.config, remember to call $scope.$digest after you replaced the html content.