In my app the User authenticates then takes a quiz. I want to save the quiz results to the User schema. When I run the following, the correct information prints to the console but saving gives me the error:
//Error printing to console:
User.save(function(err){ ^
TypeError: Object function model(doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
} has no method 'save'
//update the user with the kitten Type
app.post('/api/kittens', isLoggedIn, function (req, res, done) {
console.log(req.user.kittenType); //an empty set by default
console.log(req.body.kittenType); //the quiz result
User.findOne({ 'kittenType': req.user.kittenType}, function(err, user) {
if(err)
return done(err);
if(user) {
User.kittenType = req.body.kittenType;
User.save(function(err){
if(!err){
console.log('yay');
}
else {
console.log(err);
}
});
console.log(User.kittenType);
}
});
});
var userSchema = mongoose.Schema({
user : {
type: mongoose.Schema.ObjectId,
ref: 'User'
},
kittenType : String,
local : {
email : String,
password : String,
petname : String,
path : String,
},
});
The problem was capitalization:
should be "user.kittenType" and "user.save" not "User.save"
Related
I am using angularjs-rails-resource , in my Rails Angular App.
Account Resources
myApp.factory('Account', ['railsResourceFactory','railsSerializer', function
(railsResourceFactory,railsSerializer) {
return railsResourceFactory({
url: '/accounts',
name: 'account',
serializer: railsSerializer(function () {
this.nestedAttribute('address');
})
});
}]);
UserController.js
function userController($scope,$location,Auth,$rootScope,$http,Useraccount,Account) {
$scope.profileUpdate = function() {
//Useraccount.save(); // THIS WORKS
$scope.account = {}
$scope.account.save() // Throwing error : undefined function save
}
}
UserAccount Service
myApp.service('Useraccount',function(Auth,$location,$rootScope,Account){
var account;
var query = function(){
var promise = Account.query().then(function (results) {
account = results;
}, function (error) {
alert("Went Wrong while fetching User Account!!")
});
return promise;
}
var save = function() {
account.save().then(function (results) {
console.log(results);
}, function (error) {
alert("Went Wrong!!")
});
}
return {
query:query,
save:save
}
})
});
I am not sure why the save function from UserController is not working though I have imported Account resources as dependency. I did same in service , but it was working there. Any clue will be helpful.
You are actually calling the save() method for an empty javascript object. I don't see the point here.
Anyway you need an Angular object to do so. So either load account data from server.
$scope.accounts = Account.query(); // Will be an Array of accounts
Or create new instance of Account
$scope.account = new Account(); // An empty object
I am trying to create a modal that will tell the user their submission was successfully submitted. This works fairly well, but the only problem is I have to declare each of my properties and assign it a value, then in the Json method I have accept all those parameters then do something with them. Is there any way to do this with a ViewModel? Or any otherway that this can be done using a ViewModel?
controller:
public Json Send(string var1, string var2)
{
...
if(valid)
return new Json(true, JsonRequestBehavior.AllowGet);
else
return new Json(false, JsonRequestBehavior.AllowGet);
}
javascript:
function submitData() {
$.ajax({
url: "/Report/Send",
type: "POST",
dataType: "json",
data: { var1 = Model.var1, var2 = Model.var2... },
success: function (data) {
if(data) {
showDialog();
}
else {
$("#errorDiv").load('Report/Error/');
}
},
error: function (somefunction) { }
});
}
Yes, create a ViewModel POCO class:
var myJsonResult = new { result: true };
return Json(myJsonResult);
You can also use a strongly typed ViewModel and return that:
var myJsonResult = new CustomResult { result: true };
return Json(myJsonResult);
Then just check that property on the class in your success function:
success: function (data) {
if(data.result) {
showDialog();
}
else if(!data.result) {
$("#errorDiv").load('Report/Error/');
}
},
EDIT:
You might also want to look at jquery's .serialize() method:
data: $("#myForm").serialize()
This will be useful if you bind your ViewModel to form elements and need to post them back to the server.
Here's my issue. I'm making an ajax request to obtain an object from a controller. The object (or something) is being brought back, but I don't know how to access the attributes of that object being brought back. The object is of type "Address" and thus has attributes like Address.Address1, Address.City, etc. Here is my code: After a button is clicked,
function showEditAddress(addressid) {
$.get("/Website/Accommodation/AddressGet",
{ guid: addressid.toString() },
function(data) {
//Get values from variable 'data' such as described above
//and append to form 'dialog'
$("#dialog").dialog({
// autoOpen: false,
show: {
effect: "explode",
duration: 250
},
hide: {
effect: "explode",
duration: 250
},
buttons: {
"Save": {
text: "Save",
class: "",
click: function () {
//save form
$(this).dialog("close");
}
},
"Cancel": {
text: "Cancel",
class: "",
click: function () {
$(this).dialog("close");
}
}
},
modal: true
});
});
}
Controller action:
public Address AddressGet(string guid)
{
Guid g = new Guid(guid);
return _iCoreRepository.Addresses.Where(p => p.AddressID == g).SingleOrDefault();
}
Any help will be greatly appreciated!!! Thank you!!!
Jose is quite simple. You already answer the question. To get the value of the properties of Address you only need put a dot in front of data and type de property name. like this:
//(....)
function(data) {
//Get values from variable 'data' such as described above
//and append to form 'dialog'
//show address id.
alert(data.AddressID);
Remember that javascript is case sensitive, so you need use upper case to A and ID in AddressID like you did in C#.
And in controller you need replace the last line to something like this:
var address = _iCoreRepository.Addresses.Where(p => p.AddressID == g).SingleOrDefault();
return Json(address, JsonRequestBehavior.AllowGet);
the method must be return JsonResult. The method Json serialize the object, in this case address, in a json format before response the data to the client.
If you need the Json method accepts IEnumerables to, like List<> or Array. In javascript your data object will be a lenght property and will acess each element by using indexer like:
data[0].AddressID.
Instead of returning just your Address object you can try returning a JsonResult.
public ActionResult AddressGet(string guid)
{
Guid g = new Guid(guid);
var address = _iCoreRepository.Addresses.Where(p => p.AddressID == g).SingleOrDefault();
return Json(address, JsonRequestBehavior.AllowGet);
}
Then in your jquery, the returned data is your address object and you can access the fields as they appear in your C# class:
function showEditAddress(addressid) {
$.get("/Website/Accommodation/AddressGet",
{ guid: addressid.toString() },
function(data) {
//Get values from variable 'data' such as described above
//and append to form 'dialog'
//Access it like: data.Address1, data.City etc...
});
}
}
I am trying to use this following function to get some data.
function SaveData() {
var value = $('#tblRadio').find('input[type="radio"]:checked').val();
$.ajax({
type: "POST",
url: '/home/IsEmployeeVoted',
success: function (result) {
alert(result); // shows whole dom
if (parseInt(result) > 0) {
$('div.dvVoteWrapper').removeAttr('style');
$('div.popupArea').removeAttr('style');
}
else {
window.location = '/home/EmployeeVote?regoinID='+ value;
}
},
error: function () {
alert("Sorry, The requested property could not be found.");
}
});
}
The controller function:
public ActionResult EmployeeVote(string regionID)
{
}
regionId keep coming null to me though the value variable have some value in javascript. any ideas ??
Change
data: 'regionID=' + value,
to
data: {regionID: value},
You need to pass the data as an object literal. Another option (which I dont recommend), which is closer to your idea:
url: '/home/IsEmployeeVoted?regoinID=' + value,
But if you want this to work you would need to remove the type: 'POST' (since GET is the default type).
Few issues:
var value = $('#tblRadio').find('input[type="radio"]:checked').val();
I'd make sure that value is not undefined/null.
use alert(value) before the ajax call.
Also you are specifying GET but POSTING data to the server.
You could also wrap the regionId inside a javascript object, for instance.
$.ajax({
type: "POST",
data: { regionID: value },
url: '/home/IsEmployeeVoted',
success: function (data) {
alert(data); // shows whole dom
if (parseInt(data) > 0) {
$('div.dvVoteWrapper').removeAttr('style');
$('div.popupArea').removeAttr('style');
}
else {
window.location = "/home/EmployeeVote";
}
},
error: function () {
alert("Sorry, The requested property could not be found.");
}
});
Suppose you have the following controller action
[HttpPost]
public ActionResult Save( CustomerModel model )
{
if (!ModelState.IsValid) {
//Invalid - redisplay form with errors
return PartialView("Customer", model);
}
try {
//
// ...code to save the customer here...
//
return PartialView( "ActionCompleted" );
}
catch ( Exception ex ) {
ActionErrorModel aem = new ActionErrorModel() {
Message = ex.Message
};
return PartialView( "ActionError", aem );
}
}
And suppose you call this action using jQuery:
$.ajax({
type: "post",
dataType: "html",
url: "/Customer/Save",
sync: true,
data: $("#customerForm").serialize(),
success: function(response) {
/*
??????
*/
},
error: function(response) {
}
});
I would like to be able to distinguish between the results I am getting to handle them in different ways on the client. In other words how can I understand that the action
returned the same model because has not passed validation
returned one of the views that represents error info/messages
Any suggestion?
One way to handle this is to append a custom HTTP header to indicate in which case we are falling:
[HttpPost]
public ActionResult Save( CustomerModel model )
{
if (!ModelState.IsValid) {
//Invalid - redisplay form with errors
Response.AppendHeader("MyStatus", "case 1");
return PartialView("Customer", model);
}
try {
//
// ...code to save the customer here...
//
Response.AppendHeader("MyStatus", "case 2");
return PartialView( "ActionCompleted" );
}
catch ( Exception ex ) {
ActionErrorModel aem = new ActionErrorModel() {
Message = ex.Message
};
Response.AppendHeader("MyStatus", "case 3");
return PartialView( "ActionError", aem );
}
}
And on the client side test this header:
success: function (response, status, xml) {
var myStatus = xml.getResponseHeader('MyStatus');
// Now test the value of MyStatus to determine in which case we are
}
The benefit of this is that the custom HTTP header will always be set in the response no matter what content type you've returned. It will also work with JSON, XML, ...
Remark 1: To avoid cluttering you controller action with all those Response.AppendHeader instructions you could write a custom ActionResult allowing you to directly specify the value of this header so that you simply return this.MyPartialView("Customer", model, "case 1")
Remark 2: Remove this sync: true attribute from the request because it makes my eyes hurt (in fact I think you meant async: 'false').
You could check for an element unique to that view, for example:
$.ajax({
type: "post",
dataType: "html",
url: "/Customer/Save",
sync: true,
data: $("#customerForm").serialize(),
success: function(response) {
var resp = $(response);
if($(resp.find("#customer").length) {
//customer returned
} else if($(resp.find("#completed").length) {
//completed view
} else if($(resp.find("#error").length) {
//error view
}
},
error: function(response) {
}
});