Backbone.js router instance is somehow invalid - ruby-on-rails

I have the following chunk of code. It works perfectly.
<div id="restaurant_locations"></div>
<script type="text/javascript">
$(function() {
window.router = new Lunchhub.Routers.RestaurantLocationsRouter({restaurantLocations: <%= #restaurant_locations.to_json.html_safe -%>});
var Foo = Backbone.Router.extend({routes: {"foo":"bar"}});
r = new Foo();
Backbone.history.start();
});
</script>
However, THIS does NOT work:
<div id="restaurant_locations"></div>
<script type="text/javascript">
$(function() {
window.router = new Lunchhub.Routers.RestaurantLocationsRouter({restaurantLocations: <%= #restaurant_locations.to_json.html_safe -%>});
// All I did was delete the two lines that used to be here
Backbone.history.start();
});
</script>
The latter snippet gives me this error:
Uncaught TypeError: Cannot call method 'start' of undefined
So my Foo router instance triggers a proper initialization of Backbone.history, just like you would expect a router instance to do, but my Lunchhub.Routers.RestaurantLocationsRouter instance does not.
Here's my router definition in CoffeeScript (generated automatically by the backbone-rails gem):
class Lunchhub.Routers.RestaurantLocationsRouter extends Backbone.Router
initialize: (options) ->
#restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection()
#restaurantLocations.reset options.restaurantLocations
routes:
"new" : "newRestaurantLocation"
"index" : "index"
":id/edit" : "edit"
":id" : "show"
".*" : "index"
newRestaurantLocation: ->
#view = new Lunchhub.Views.RestaurantLocations.NewView(collection: #restaurant_locations)
$("#restaurant_locations").html(#view.render().el)
index: ->
#view = new Lunchhub.Views.RestaurantLocations.IndexView(restaurant_locations: #restaurant_locations)
$("#restaurant_locations").html(#view.render().el)
show: (id) ->
restaurant_location = #restaurant_locations.get(id)
#view = new Lunchhub.Views.RestaurantLocations.ShowView(model: restaurant_location)
$("#restaurant_locations").html(#view.render().el)
edit: (id) ->
restaurant_location = #restaurant_locations.get(id)
#view = new Lunchhub.Views.RestaurantLocations.EditView(model: restaurant_location)
$("#restaurant_locations").html(#view.render().el)
And here's the compiled JavaScript:
(function() {
var __hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
Lunchhub.Routers.RestaurantLocationsRouter = (function(_super) {
__extends(RestaurantLocationsRouter, _super);
function RestaurantLocationsRouter() {
RestaurantLocationsRouter.__super__.constructor.apply(this, arguments);
}
RestaurantLocationsRouter.prototype.initialize = function(options) {
this.restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection();
return this.restaurantLocations.reset(options.restaurantLocations);
};
RestaurantLocationsRouter.prototype.routes = {
"new": "newRestaurantLocation",
"index": "index",
":id/edit": "edit",
":id": "show",
".*": "index"
};
RestaurantLocationsRouter.prototype.newRestaurantLocation = function() {
this.view = new Lunchhub.Views.RestaurantLocations.NewView({
collection: this.restaurant_locations
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.index = function() {
this.view = new Lunchhub.Views.RestaurantLocations.IndexView({
restaurant_locations: this.restaurant_locations
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.show = function(id) {
var restaurant_location;
restaurant_location = this.restaurant_locations.get(id);
this.view = new Lunchhub.Views.RestaurantLocations.ShowView({
model: restaurant_location
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.edit = function(id) {
var restaurant_location;
restaurant_location = this.restaurant_locations.get(id);
this.view = new Lunchhub.Views.RestaurantLocations.EditView({
model: restaurant_location
});
return $("#restaurant_locations").html(this.view.render().el);
};
return RestaurantLocationsRouter;
})(Backbone.Router);
}).call(this);
What could be going wrong here?
EDIT: I've figured out part of the problem. In the CoffeeScript, it was using restaurant_locations in some places where it should have been using restaurantLocations. I'm having a strange problem now, but potentially an easier one: when I copy and paste the compiled JavaScript directly into <script> area, right before the window.router = assignment, everything works perfectly. However, when I try to use the compiled JS as an external file (and I know it's being included - I checked), I get that same Cannot call method 'start' of undefined error.
Here's my updated CoffeeScript:
class Lunchhub.Routers.RestaurantLocationsRouter extends Backbone.Router
initialize: (options) ->
#restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection()
#restaurantLocations.reset options.restaurantLocations
routes:
"new" : "newRestaurantLocation"
"index" : "index"
":id/edit" : "edit"
":id" : "show"
".*" : "index"
newRestaurantLocation: ->
#view = new Lunchhub.Views.RestaurantLocations.NewView(collection: #restaurantLocations)
$("#restaurant_locations").html(#view.render().el)
index: ->
#view = new Lunchhub.Views.RestaurantLocations.IndexView(restaurantLocations: #restaurantLocations)
$("#restaurant_locations").html(#view.render().el)
show: (id) ->
restaurant_location = #restaurantLocations.get(id)
#view = new Lunchhub.Views.RestaurantLocations.ShowView(model: restaurant_location)
$("#restaurant_locations").html(#view.render().el)
edit: (id) ->
restaurant_location = #restaurantLocations.get(id)
#view = new Lunchhub.Views.RestaurantLocations.EditView(model: restaurant_location)
$("#restaurant_locations").html(#view.render().el)
And here's my updated compiled JavaScript:
(function() {
var __hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
Lunchhub.Routers.RestaurantLocationsRouter = (function(_super) {
__extends(RestaurantLocationsRouter, _super);
function RestaurantLocationsRouter() {
RestaurantLocationsRouter.__super__.constructor.apply(this, arguments);
}
RestaurantLocationsRouter.prototype.initialize = function(options) {
this.restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection();
return this.restaurantLocations.reset(options.restaurantLocations);
};
RestaurantLocationsRouter.prototype.routes = {
"new": "newRestaurantLocation",
"index": "index",
":id/edit": "edit",
":id": "show",
".*": "index"
};
RestaurantLocationsRouter.prototype.newRestaurantLocation = function() {
this.view = new Lunchhub.Views.RestaurantLocations.NewView({
collection: this.restaurantLocations
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.index = function() {
this.view = new Lunchhub.Views.RestaurantLocations.IndexView({
restaurantLocations: this.restaurantLocations
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.show = function(id) {
var restaurant_location;
restaurant_location = this.restaurantLocations.get(id);
this.view = new Lunchhub.Views.RestaurantLocations.ShowView({
model: restaurant_location
});
return $("#restaurant_locations").html(this.view.render().el);
};
RestaurantLocationsRouter.prototype.edit = function(id) {
var restaurant_location;
restaurant_location = this.restaurantLocations.get(id);
this.view = new Lunchhub.Views.RestaurantLocations.EditView({
model: restaurant_location
});
return $("#restaurant_locations").html(this.view.render().el);
};
return RestaurantLocationsRouter;
})(Backbone.Router);
}).call(this);

Okay, this turned out to be a pretty esoteric problem. I had had a leftover backbone-min.js sitting in my app/assets/javascripts directory, even though I had switched to using a different Backbone file. This "old" backbone-min.js was getting loaded after my route definition and that's what was messing things up. After I deleted backbone-min.js, things started working.

Related

I have a 404 error in an Ajax call on Ruby on rails

I'm pretty new to ajax (and web development in general) and I'm trying to implement this code directly on my view:
<% content_for :after_js do %>
<script type="text/javascript">
//1st dropdown selection
const dropdownOne = document.querySelector('#order_credits_package_id');
//Listening to dropdown change
dropdownOne.addEventListener('change', (event) => {
const selectedPackage = event.target.value
console.log(selectedPackage)
// document.getElementById("order_amount_centavos").value = event.target.value
// Params for AJAX call
const url = "/dynamic_dropdown_method";
const data = {'selection': selectedPackage }
// Storage of AJAX call answer (NB: can be refactored to avoid 2 calls)
// the ['id'] must match the one defined in your controller
const level_1_selected = ajaxCall(url, data)['dropdown_1_selected'];
const level_2_array = ajaxCall(url, data)['dropdown_2_array'];
// Identification of 2nd dropdown
const dropdownTwo = document.querySelector('#order_amount_centavos');
// Delete and replace options in 2nd dropdown
removeOptions(dropdownTwo);
addOptions(level_2_array, dropdownTwo)
});
// AJAX call
function ajaxCall(url,data) {
var result = "";
console.log("call Ajax")
console.log(url)
console.log(data)
$.ajax({
url: url,
async: false,
dataType: 'json',
type: 'POST',
data: data,
success: function (response) {
console.log("ajax Call")
console.log(response)
result = response;
}
});
return result;
}
// Delete existing select options
function removeOptions(selectElement) {
console.log("fonction remove")
var i, L = selectElement.options.length - 1;
for(i = L; i >= 0; i--) {
selectElement.remove(i);
}
}
// Add select option
function addOptions(optionsArray, dropdown) {
optionsArray.forEach(function (item) {
const new_option = document.createElement('option');
new_option.value = item;
new_option.innerHTML = item;
dropdown.appendChild(new_option);
});
}
</script>
<% end %>
I then added this method to the controller related to this view:
def dynamic_dropdown_method
#selection = params[:credits_package_id]
#array_dropdown_2 = CreditsPackage.find(#selection).price_centavos
return render json: {level_1_selected: #selection, level_2_array: #array_dropdown_2}.to_json
end
And the following route:
post "/dynamic_dropdown_method", to: "orders#dynamic_dropdown_method", as: :dynamic_dropdown_method
But when I try to run my code, I get the following error message in the console:
POST http://localhost:3000/dynamic_dropdown_method 404 (Not Found)
Does anyone have any idea how to fix it?
Thank you very much!

Error in ODataMetadata.js SAP Hana Cloud

In the app that I am creating I have a home view when the createCaseButton is clicked the createCase view is opened, but when I click to open this view I am getting the following error please see attached image. I can't seem to figure out why it is doing this. Any help would be amazing
Errors in console
Here is my code:
CreateCase controller:
jQuery.sap.require("sap.ui.commons.MessageBox");
sap.ui.controller("casemanagement.CreateCase", {
onInit: function() {
var sOrigin = window.location.protocol + "//" + window.location.hostname
+ (window.location.port ? ":" + window.location.port : "");
var caseTrackerOdataServiceUrl = sOrigin + "/CaseTracker/#/case.svc";
var odataModel = new sap.ui.model.odata.ODataModel(caseTrackerOdataServiceUrl);
odataModel.setCountSupported(false);
this.getView().setModel(odataModel);
},
AddCase : function(aCaseType,aReason,aDateOpened,aEmployee,aDescription,aComment,aAttachment){
if(aCaseType != "" && aReason != "" && aDateOpened != "" && aEmployee != "" && aDescription != "" && aComment != "")
{
var Cases = {};
Cases.caseTypeId = aCaseType;
Cases.reasonId = aReason;
Cases.dateOpened = aDateOpened;
Cases.employeeId = aEmployee;
Cases.description = aDescription;
Cases.comments = aComment;
Cases.stageId = "open"
this.getView().getModel().create("/CreateCase", Cases, null, this.successMsg, this.errorMsg);
Cases = {};
this.router = sap.ui.core.UIComponent.getRouterFor(this);
this.router.navTo("CreateCasePage");
}
else
{
sap.ui.commons.MessageBox.alert("Please fill in all fields before submitting")
}
},
successMsg : function() {
sap.ui.commons.MessageBox.alert("Case has been successfully created");
},
errorMsg : function() {
sap.ui.commons.MessageBox.alert("Error occured when creating the case");
},
CreateCase View:
sap.ui.jsview("casemanagement.CreateCase", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* #memberOf casemanagement.CreateCase.CreateCase
*/
getControllerName : function() {
return "casemanagement.CreateCase";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* #memberOf casemanagement.CreateCase.CreateCase
*/
createContent : function(oController) {
var aPanel = new sap.ui.commons.Panel({width:"810px"});
aPanel.setTitle(new sap.ui.core.Title({text:"Create New Case"}));
var aMatrix = new sap.ui.commons.layout.MatrixLayout({layoutFixed:true, width:"610px",columns:8});
aMatrix.setWidths("110px","100px","100px","300px");
var bMatrix = new sap.ui.commons.layout.MatrixLayout({layoutFixed:true,width:"610px", columns:2});
aMatrix.setWidths("110px","500px");
//first row of fields
var caseTypeLabel = new sap.ui.commons.Label({text:"Case Type"});
var caseTypeInput = new sap.ui.commons.TextField({width:"100%", id:"caseTypeId", value:''});
caseTypeLabel.setLabelFor(caseTypeInput);
aMatrix.createRow(caseTypeLabel,caseTypeInput);
//second row
var reasonLabel = new sap.ui.commons.Label({text:"Reason"});
var reasonInput = new sap.ui.commons.TextField({width:"100%", id:"reasonId", value:''});
reasonLabel.setLabelFor(reasonInput);
aMatrix.createRow(reasonLabel,reasonInput);
//third row
var dateOpenedLabel = new sap.ui.commons.Label({text:"Date Opened"});
var dateOpenedInput = new sap.ui.commons.TextField({widht:"100%", id: "dateOpenedId", value:''});
dateOpenedLabel.setLabelFor(dateOpenedInput);
aMatrix.createRow(dateOpenedLabel,dateOpenedInput)
//fourth row
var employeeLabel = new sap.ui.commons.Label({text:"Employee"});
var employeeIDInput = new sap.ui.commons.TextField({width:"100%", id:"employeeId",value:''});
var employeeNameInput = new sap.ui.commons.TextField({width:"100%"});
aMatrix.createRow(employeeLabel,employeeIDInput,employeeNameInput);
//fifth row
var descriptionLabel = new sap.ui.commons.Label({text:"Description"});
var descriptionInput = new sap.ui.commons.TextField({width:"100%",id:"descriptionId",value:''});
descriptionLabel.setLabelFor(descriptionInput);
aMatrix.createRow(descriptionLabel,descriptionInput)
aPanel.addContent(aMatrix);
var bPanel = new sap.ui.commons.Panel({width:"810px"});
bPanel.setTitle(new sap.ui.core.Title({text:"Actions"}));
bPanel.setCollapsed(false);
var cMatrix = new sap.ui.commons.layout.MatrixLayout({layoutFixed:true,width:"810px",columns:2});
cMatrix.setWidths("110px","700px");
var attachmentLabel = new sap.ui.commons.Label({text:"Attachments"});
var addAttachmentButton = new sap.ui.commons.FileUploader({
uploadUrl : "../../../../../upload",
name: "attachmentUploader",
uploadOnChange: true
});
var commentsLabel = new sap.ui.commons.Label({text:"Comments"});
var commentsInput = new sap.ui.commons.TextField({width:"95%",id:"commentsId",value:''});
var submitButton = new sap.ui.commons.Button({id:"createCaseButtonId",text:"Submit", press : function(){oController.AddCase(
sap.ui.getCore().getControl("caseTypeId").getValue(),
sap.ui.getCore().getControl("reasonId").getValue(),
sap.ui.getCore().getControl("dateOpenedId").getValue(),
sap.ui.getCore().getControl("employeeId").getValue(),
sap.ui.getCore().getControl("descriptionId").getValue(),
sap.ui.getCore().getControl("commentsId").getValue()
)}
});
cMatrix.createRow(attachmentLabel,addAttachmentButton);
cMatrix.createRow(commentsLabel,commentsInput);
cMatrix.createRow(submitButton);
bPanel.addContent(cMatrix);
var container = new sap.ui.layout.VerticalLayout({
content: [aPanel,bPanel]
});
return container;
},
});
Home controller:
sap.ui.controller("casemanagement.Home", {
/**
* Called when a controller is instantiated and its View controls (if
* available) are already created. Can be used to modify the View before it
* is displayed, to bind event handlers and do other one-time
* initialization.
*
* #memberOf casemanagement.Home.Home
*/
// onInit : function() {
//
// },
loadCreateCase : function() {
this.router = sap.ui.core.UIComponent.getRouterFor(this);
this.router.navTo("CreateCasePage");
},
loadSearchCase : function() {
this.router = sap.ui.core.UIComponent.getRouterFor(this);
this.router.navTo("SearchCasePage");
}
Home view:
sap.ui.jsview("casemanagement.Home", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* #memberOf casemanagement.Home.Home
*/
getControllerName : function() {
return "casemanagement.Home";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* #memberOf casemanagement.Home.Home
*/
createContent : function(oController) {
var oPanelButtons = new sap.ui.commons.Panel({width:"600px",position:"center"});
oPanelButtons.setTitle(new sap.ui.core.Title({text:"Case Management"}));
var oMatrix = new sap.ui.commons.layout.MatrixLayout({layoutFixed: true, width:"400px",columns:4, position:"center"});
oMatrix.setWidths("100px","100px","100px","100px");
var createCaseButton = new sap.ui.commons.Button({id:'createId',text:"Create Case",press : function(){oController.loadCreateCase()}});
var searchButton = new sap.ui.commons.Button({text:"Search Cases",press : function(){oController.loadSearchCase()}});
var analyticsButton = new sap.ui.commons.Button({id:'analyticsId',text:"Case Analytics"});
var helpButton = new sap.ui.commons.Button({id:'helpId',text:"Help"});
oMatrix.createRow(createCaseButton,searchButton,analyticsButton,helpButton);
oPanelButtons.addContent(oMatrix);
var oPanelTable = new sap.ui.commons.Panel({width:"600px",position:"center"});
var oTable = new sap.m.Table({
inset: true,
headerText: "Open Cases Pending Your Action",
headerDesign : sap.m.ListHeaderDesign.Standard,
mode: sap.m.ListMode.None,
includeItemInSelection: true
});
oTable.addColumn(new sap.m.Column({
inset : true,
header: new sap.ui.commons.Label({text: "Case#"}),
}));
oTable.addColumn(new sap.m.Column({
inset : true,
header: new sap.ui.commons.Label({text: "Submitted By"}),
}));
oTable.addColumn(new sap.m.Column({
inset : true,
header: new sap.ui.commons.Label({text: "Created On"}),
}));
oTable.addColumn(new sap.m.Column({
inset : true,
header: new sap.ui.commons.Label({text: "Case Type"}),
}));
oPanelTable.addContent(oTable);
var container = new sap.ui.layout.VerticalLayout({
id: "container",
content:[oPanelButtons,oPanelTable]
});
return container;
},
});

Worker path is not fired error says 404 (Not Found)

Reference doc:- https://github.com/ajaxorg/ace/wiki/Syntax-validation
I added createWorker method to the custom mode according to the above doc, and included the worker-example.js in the same file and called require("ace/config").set("workerPath", "ace/mode") in mode definition
Currently, the workerPath is not being fired, I'm seeing a "GET http://localhost:3000/ace/mode/worker-example.js 404 (Not Found)" error in the console.
Here is my custom code index.html.erb :
define('ace/mode/example-custom', [], function(require, exports, module) {
var oop = require("ace/lib/oop");
var TextMode = require("ace/mode/text").Mode;
var Tokenizer = require("ace/tokenizer").Tokenizer;
var ExampleHighlightRules = require("ace/mode/example_highlight_rules").ExampleHighlightRules;
var WorkerClient = require("ace/worker/worker_client").WorkerClient;
require("ace/config").set("workerPath", "ace/mode");
var Mode = function() {
this.HighlightRules = ExampleHighlightRules;
};
oop.inherits(Mode, TextMode);
(function() {
this.lineCommentStart = "--";
this.blockComment = {start: "->", end: "<-"};
this.createWorker = function(session) {
var worker = new WorkerClient(["ace"], workerpath, "WorkerExample");
worker.attachToDocument(session.getDocument());
console.log("worker", worker);
worker.on("errors", function(e) {
session.setAnnotations(e.data);
});
worker.on("annotate", function(results) {
session.setAnnotations(results.data);
});
worker.on("terminate", function() {
session.clearAnnotations();
});
return worker;
};
define('ace/mode/worker-example', [], function(require, exports, module) {
var oop = require("ace/lib/oop");
var Mirror = require("ace/worker/mirror").Mirror;
var WorkerExample = exports.WorkerExample = function(sender) {
Mirror.call(this, sender);
this.setTimeout(200);
};
oop.inherits(WorkerExample, Mirror);
(function() {
this.onUpdate = function() {
var lines = editor.session.doc.getAllLines();
var errors = [];
for (var i = 0; i < lines.length; i++){
if (/[\w\d{(['"]/.test(lines[i])) {
alert("hello");
errors.push({
row: i,
column: lines[i].length,
text: "Missing Semicolon",
type: "error"
});
}
}
this.sender.emit("annotate", errors);
};
}).call(WorkerExample.prototype);
});

Backbone.js - How to save model by form and post to server

I'm n00b in BackboneJS/RequireJS and I'm developing an web app that use a RESTful API.
So I've a model like this:
models/pet.js
define([
'backbone'
], function(Backbone){
var PetModel = Backbone.Model.extend({
urlRoot: 'http://localhost:3000/pet',
idAttribute: '_id',
defaults: {
petId: "",
type: "",
name: "",
picture: "",
description: "",
breed: "",
size: "",
sex: "",
age: "",
adopted: false,
}
});
return PetModel;
});
a collection: collections/pets.js
define([
'backbone',
'models/pet'
], function(Backbone, PetModel){
var PetsCollection = Backbone.Collection.extend({
url: 'http://localhost:3000/pets',
model: PetModel,
});
return PetsCollection;
});
And a view that renders a form to add new models (Maybe it's possible another way more elegant)
views/petAddNew.js
define([
'jquery',
'backbone',
'models/pet',
'collections/pets',
'text!templates/pet/addNew.html'
], function($, Backbone, PetModel, PetsCollection, petAddNewTemplate){
var PetAddNewView = Backbone.View.extend({
el: $('#formAdd'),
template: _.template(petAddNewTemplate),
events: {
'click #add' : 'submitAdd',
},
initialize: function() {
this.model = new PetModel();
this.collection = new PetsCollection();
_.bindAll(this, 'submitAdd');
},
render: function() {
var view = this;
view.$el.html( view.template );
return view;
},
submitAdd: function(e) {
//Save Animal model to server data
e.preventDefault();
var pet_data = JSON.stringify( this.getFormData( this.$el.find('form') ) );
this.model.save(pet_data);
this.collection.add(this.model);
return false
},
//Auxiliar function
getFormData: function(form) {
var unindexed_array = form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function(n, i){
indexed_array[n['name']] = n['value'];
});
return indexed_array;
},
});
return PetAddNewView;
});
So when I submit the form I don't post any data to server. I don't know how to fix it.
Any ideas? Thanks in advance!
You need set the attributes first and then save.
//Auxiliar function
getFormData: function(form) {
var self = this;
var unindexed_array = form.serializeArray();
$.map(unindexed_array, function(n, i){
self.model.set({
n['name']: n['value']
});
});
}
Now this.model.save() works (saving on the server side).
You can see it work in a fiddle.
Model.save expect an object/hash of new values, just like Model.set. Here you're passing a string as the attributes arguments.

show records in Angularjs - newbie

This is a real newbie question:
I have a view for my index in Rails in erb:
<div ng-app="Donor">
<div ng-controller="DonorCtrl">
<ul>
<li ng-repeat="donor in donors">
{{donor}}
</li>
</ul>
</div>
</div>
my Donor json returned from Rails is:
class DonorSerializer < ActiveModel::Serializer
attributes :id, :tools_id, :first_name, :last_name
end
My javascript file has this;
var app;
app = angular.module("Donor", ["ngResource"]);
// separate view to Add new donors
$scope.addDonor = function() {
var donor;
donor = Entry.save($scope.newDonor);
$scope.donors.push(entry);
return $scope.newDonor = {};
};
$scope.showDonors = function() {
var Donor = $resource("/donors", {
update: {
method: "GET"
}
});
return $scope.donors = Donor;
}
this.DonorCtrl = function($scope, $resource) {
var Donor;
Donor = $resource("/donors/:id", {
id: "#id"
}, {
update: {
method: "PUT"
}
});
return $scope.donors = Donor.query();
};
How do I get a list of donors to in my index view?
I am missing something
One of your first issues was that you did not have the right code inside of the controller. I also turned your $resource's into factory's. I changed the Donors update method to 'PUT' since you have an 'addDonor' method.
Make sure you also have the proper libraries setup for angularjs. For this you will need:
angular.js
angular-resource.js
The altered Javascript:
var app;
app = angular.module("Donor", ["ngResource"]);
app.factory("Donors", [
"$resource", function($resource) {
return $resource("/donors", {}, {
update: {
method: "PUT"
}
});
}
]);
app.factory("Donor", [
"$resource", function($resource) {
return $resource("/donors/:id", {
id: "#id"
}, {
update: {
method: "GET"
}
});
}
]);
this.DonorCtrl = [
"$scope", "Donor", "Donors", function($scope, Donor, Donors) {
var donor;
$scope.donor = Donor.query();
$scope.donors = Donors.query();
$scope.addDonor = function() {};
donor = Donor.save($scope.newDonor)(function() {
return $scope.donors.push(donor);
});
return $scope.newDonor = {};
}
];
Since you are using rails, here is the coffeescript version (I find it elegant in combination with angularjs):
app = angular.module("Donor", ["ngResource"])
app.factory "Donors", ["$resource", ($resource) ->
$resource("/donors", {}, {update: {method: "PUT"}})
]
app.factory "Donor", ["$resource", ($resource) ->
$resource("/donors/:id", {id: "#id"}, {update: {method: "GET"}})
]
#DonorCtrl = ["$scope", "Donor", "Donors", ($scope, Donor, Donors) ->
$scope.donor = Donor.query()
$scope.donors = Donors.query()
$scope.addDonor = ->
donor = Donor.save($scope.newDonor) ->
$scope.donors.push donor
$scope.newDonor = {}
]
I would checkout EggHead.io for a better understanding of how to setup your angular javascript files.

Resources