rikkitikkitumbo
rikkitikkitumbo

Reputation: 976

ng-resource in Rails. AngularJS + Rails tutorial

I'm trying to use ng-resource to show an index of book titles. This is ch.11 of AngulaRails, which so far has been really tough.

I know my problem has to do with trying to to use a resource in my coffeescript controller, because when I just us an $http "get" request with a specific url, things work fine. Here are all the parts of my code for this:

1.javscripts/application.js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require angular.min
//= require angular-resource

//= require angular-application

2 Serializer:

class BookSerializer < ActiveModel::Serializer
  attributes :id, :title, :author

end

3 this works fine:

AngulaRails.config ["$httpProvider", ($httpProvider) ->
  $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
  $httpProvider.defaults.headers.common.Accept = "application/json"
]

4 javascripts/angular-application.js

//= require_self
//= require_tree ./angular

AngulaRails = angular.module("AngulaRails", ["ngResource"]);

5 the index controller for the index I'm trying to look at:

  # GET /books
  def index
    @books = Book.all

    respond_to do |format|
      format.html {   }
      format.json { render json: @books, root: false, each_serializer: BookSerializer }
    end
  end

6 The factory for the resource I'm trying to use. In this case, I'm calling the query for the index:

AngulaRails.factory "Book", ($resource) ->
  $resource("/books/:id")
  {
  'get':    {method: 'GET'},
  'save':   {method: 'POST'},
  'query':  {method: 'GET', isArray: true},
  'remove': {method: 'DELETE'},
  'delete': {method: 'DELETE'}
  }

7 last but not least, the coffescript controller for this app:

AngulaRails.controller "BooksController", ($scope,  Book) ->
  $scope.getBooks = () ->
    $scope.books = Book.query()

When I try to run this, the console.log will give me an error saying:

Error: Book.query is not a function

Upvotes: 1

Views: 2188

Answers (3)

rikkitikkitumbo
rikkitikkitumbo

Reputation: 976

The main problem was that I had another factory going, and it was after this one in my asset pipeline, so rails used IT and over-rided this one. shaking my head

but yes, this hash wasn't necessary:

{
  'get':    {method: 'GET'},
  'save':   {method: 'POST'},
  'query':  {method: 'GET', isArray: true},
  'remove': {method: 'DELETE'},
  'delete': {method: 'DELETE'}
  }

Upvotes: 0

soosap
soosap

Reputation: 1445

there is indeed a problem with your factory declaration. You do not need to include the allocation of actions to the request types of 'GET', 'POST' etc. as it this is the default setting.

The only issue that might arise is with the update action that shows to the POST request by default. However, a PUT request might be more reasonable for the purpose of updating a data record. Therefore, I included {update: {method: "PUT"}} which is overwriting the default.

Credit: AngulaRails book. This works:

  AngulaRails.factory "Book", ($resource) ->
    $resource("/books/:id", {id: "@id"}, {update: {method: "PUT"}})

If, however, you want to include it explicitly, watch out for setting the brackets correctly.

AngulaRails.factory "Book", ($resource) ->
  $resource("/books/:id", {id: "@id"},
  {
   get:    {method: 'GET'},
   save:   {method: 'POST'},
   query:  {method: 'GET', isArray: true},
   remove: {method: 'DELETE'},
   delete: {method: 'DELETE'}
   update: {method: "PUT"}
  })

Upvotes: 2

Anthony Chu
Anthony Chu

Reputation: 37530

There's a problem with the factory declaration. It's returning this object:

  {
  'get':    {method: 'GET'},
  'save':   {method: 'POST'},
  'query':  {method: 'GET', isArray: true},
  'remove': {method: 'DELETE'},
  'delete': {method: 'DELETE'}
  }

... whose query property is an object, not a function... hence the error. This is probably what you meant...

($resource) ->
  $resource("/books/:id", {}, 
  {
  'get':    {method: 'GET'},
  'save':   {method: 'POST'},
  'query':  {method: 'GET', isArray: true},
  'remove': {method: 'DELETE'},
  'delete': {method: 'DELETE'}
  })

Upvotes: 0

Related Questions