Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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();
}]);
share|improve this question
    
What is your question? –  Beerlington Apr 10 at 18:15
    
I edited it out accidentally. Still I thought it was obvious. Angularjs templates are not being called. Neither are rails templates. Just json. –  Xavier Apr 10 at 18:19
    
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. –  Beerlington Apr 10 at 18:24
    
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? –  Xavier Apr 10 at 18:29

1 Answer 1

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.

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

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.

share|improve this answer
    
What I actually wanted to do was the standard angularjs use case. I needed to route all incoming server requests to bypass the rails router and go to angularjs routes. I used root to: application#home' get "*path" => "application#home". Then in that controller I put in render :layout => 'application', :nothing => true since no server side view is rendered. –  Xavier May 21 at 17:41
    
If you asked Rails to render nothing, then how do you get the user data into your view? Say if it is a single page site/or api service, you can render the json with js/json calls (Rails controller still need to render :json @user, otherwise there is nothing returned). Then the index page/client app will need to pre-load with the angular scripts before first json call. which means index page can't be json. you can take a look this <railscasts.com/episodes/405-angularjs>; –  Jie Cai May 22 at 11:10
    
Try use Rails to render html + angular script for "/" and use angular.config to handle the rest of routing. –  Jie Cai May 22 at 23:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.