1

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

3 Answers 3

2

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"}
  })
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the answer!! 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****
0

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'}
  })

1 Comment

tried it, but still getting the same "Book.query is not a function" error
0

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'}
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.