Reputation: 92
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'
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"
}
]
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:in
create'
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.
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:in
listItem_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?
Upvotes: 0
Views: 1201
Reputation: 92
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!
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!!
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 : )
Upvotes: 1