0

I have a list and each list may contain 0 or more items. I'm new to Angularjs and I'm using angularJS $resource to to POST to my rails backend API for creating this list with items. If I create a test array like below and use ListItem.save $scope.test then this POST completes successfully to my Rails backend api.

$scope.test = 'item_id': '55' 'qty': '6' 'uom': 'each'

Processing by Api::V1::ListItemsController#create as JSON

Parameters: {"item_id"=>"55", "qty"=>"6", "uom"=>"each", "list_id"=>"14", "list_item"=>{"item_id"=>"55", "qty"=>"6", "uom"=>"each"}} List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 14]] (0.1ms) begin transaction SQL (0.3ms) INSERT INTO "list_items" ("item_id", "qty", "uom", "list_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["item_id", 55], ["qty", 6], ["uom", "each"], ["list_id", 14], ["created_at", "2015-06-06 06:14:12.844167"], ["updated_at", "2015-06-06 06:14:12.844167"]] (2.0ms) commit transaction Completed 200 OK in 7ms (Views: 0.5ms | ActiveRecord: 2.6ms) woohoo!!!

However things quickly fall apart when I create a json array in my controller and try to save this array. Then this does not complete successfully (error below)

[ { "item_id": 32, "qty": "1", "uom": "Dozen" } ]

Processing by Api::V1::ListItemsController#create as JSON

Parameters: {"_json"=>[{"item_id"=>34, "qty"=>"1", "uom"=>"Each"}], "list_id"=>"14", "list_item"=>{}} List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 14]] Completed 400 Bad Request in 2ms ActionController::ParameterMissing (param is missing or the value is empty: list_item): app/controllers/api/v1/list_items_controller.rb:50:in listItem_params' app/controllers/api/v1/list_items_controller.rb:21:increate'

I even tried to add the list_item object to the json array using ListItem.save {list_item: $scope.final} and then a different error is received below.

Processing by Api::V1::ListItemsController#create as JSON

Parameters: {"list_item"=>[{"item_id"=>30, "qty"=>"1", "uom"=>"Each"}], "list_id"=>"14"} List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 14]] Completed 500 Internal Server Error in 2ms NoMethodError (undefined method permit' for [{"item_id"=>30, "qty"=>"1", "uom"=>"Each"}]:Array): app/controllers/api/v1/list_items_controller.rb:50:inlistItem_params' app/controllers/api/v1/list_items_controller.rb:21:in `create'

list_items_controller

    module Api
  module V1
class ListItemsController < ApplicationController
  protect_from_forgery
  skip_before_action :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
  before_action :set_list
  respond_to :json

  def index
    respond_with ListItem.all
  end

  def new
  end

  def create
    @li = @list.list_items.new(listItem_params)
      if @li.save
        render :status => 200,
           :json => { :success => true,
                      :info => "ItemAdded",
                      :data => { :item => @li }}
      else
        render :status => :unprocessable_entity,
           :json => { :success => false,
                      :info => resource.errors,
                      :data => {} }                              
      end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_list
      @list = List.find(params[:list_id])
    end

    def listItem_params
      params.require(:list_item).permit(:list_id, :item_id, :qty, :uom)
           end
      protected

        def json_request?
          request.format.json?
        end
    end
  end
end

lists.coffee (relevant sections)

    app = angular.module('myApp', [ 'ngResource' ])

ListItem = app.factory('ListItem', ($resource) ->

  $resource '/api/v1/lists/14/list_items/:id', { id: '@id' }, update: method: 'PUT'
)
app.controller 'myCtrl', ($scope, ListItem) ->
  $scope.selection = []
  $scope.final = []
  $scope.test =
  'item_id': '55'
  'qty': '6'
  'uom': 'each'

  $scope.saveListItems = ()->
    i = 0
    while i < $scope.selection.length
      obj = $scope.selection[i]
      $scope.final.push 
        'item_id': obj.id
        'qty': obj.qty
        'uom': obj.uom
      li= ""
      li = ListItem.save $scope.final
      i++

selection array will contain the following for example when I add an item to the selection.

[
  {
    "id": 32,
    "name": "Eggs",
    "created_at": "2015-04-29T00:14:19.627Z",
    "updated_at": "2015-04-29T00:14:19.627Z",
    "user_id": null,
    "qty": "1",
    "uom": "Dozen"
  }
 ]

And when I click the confirm button then the saveListItems function is executed

<button class="btn btn-lg btn-primary" ng-click="saveListItems()">Confirm</button>

the final array contains the following after the saveListItems function is run:

[
  {
    "item_id": 32,
    "qty": "1",
    "uom": "Dozen"
  }
]

I would like to have angularjs build the array correctly so that it will POST a new list item successfully to my rails backend api. Any suggestions on how to fix this?

1 Answer 1

1

I found a similar SO question here How do I save an Angular form to my ruby on rails backend?

And instead of using $resource I used $http in the saveListItems function as shown below:

  $scope.saveListItems = ->
    i = 0
    while i < $scope.selection.length
      obj = $scope.selection[i]
      $scope.final = 'list_item':
        'item_id': obj.id
        'qty': obj.qty
        'uom': obj.uom
      $http
        method: 'POST'
        url: 'http://192.168.0.6:3000/api/v1/lists/14/list_items'
        data: $scope.final
      return
      i++

Next, I included the $http service in the controller like this:

app.controller 'myCtrl', ($scope, ListItem, $http) ->

Retested and it worked!

Processing by Api::V1::ListItemsController#create as JSON

Parameters: {"list_item"=>{"item_id"=>56, "qty"=>"2", "uom"=>"Dozen"}, "list_id"=>"14"} List Load (0.2ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 14]] (0.1ms) begin transaction SQL (0.4ms) INSERT INTO "list_items" ("item_id", "qty", "uom", "list_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["item_id", 56], ["qty", 2], ["uom", "Dozen"], ["list_id", 14], ["created_at", "2015-06-06 23:50:30.564950"], ["updated_at", "2015-06-06 23:50:30.564950"]] (1.8ms) commit transaction Completed 200 OK in 6ms (Views: 0.4ms | ActiveRecord: 2.3ms) waahoo!!

I then re-tested with $resource but changed the saveListItems function as shown below:

  $scope.saveListItems = ->
    i = 0
    while i < $scope.selection.length
      obj = $scope.selection[i]
      $scope.final = 'list_item':
        'item_id': obj.id
        'qty': obj.qty
        'uom': obj.uom
      ListItem.save($scope.final)
      i++


    return

And next, I removed the $http service from the controller

app.controller 'myCtrl', ($scope, ListItem) ->

This also worked!!

Processing by Api::V1::ListItemsController#create as JSON

Parameters: {"list_item"=>{"item_id"=>60, "qty"=>"4", "uom"=>"Each"}, "list_id"=>"14"} List Load (0.2ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 14]] (0.1ms) begin transaction SQL (0.4ms) INSERT INTO "list_items" ("item_id", "qty", "uom", "list_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["item_id", 60], ["qty", 4], ["uom", "Each"], ["list_id", 14], ["created_at", "2015-06-07 00:27:12.125078"], ["updated_at", "2015-06-07 00:27:12.125078"]] (2.2ms) commit transaction Completed 200 OK in 8ms (Views: 0.5ms | ActiveRecord: 2.8ms)

Hope this info helps others. I'm sure this code can use some serious refactoring though as I'm still learning Angularjs so that's my disclaimer : )

Sign up to request clarification or add additional context in comments.

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.