Angular ngResource's $save() not working - javascript

I want to post data to my asp.net webapi controller, by using $save() method that belong to ngResource i am getting this error:
"TypeError: $scope.product.$save is not a function at n.$scope.saveProduct "
when i used $http(), data is getting saved but $save() is giving me error, other methods like $query() and $get() are working properly only $save() is causing an error.
code:
// first file (module)
var app = angular.module('commonServices', ['ngResource'])
.constant('appSettings', {
serverPath: 'http://localhost:29904/'
});
//second file (factory)
(function(){
angular.module('commonServices')
.factory('productResource', ['$resource', 'appSettings', productResource])
function productResource($resource, appSettings) {
return $resource(appSettings.serverPath + "api/Products/:id",
null,
{
'update': { method: 'PUT' },
});
}
}());
// third file (controller)
myApp.controller('editProductController', ['$scope', '$routeParams', '$http', 'productResource',
function ($scope, $routeParams, $http, productResource) {
$scope.num = $routeParams.id;
$scope.alertUser = false;
$scope.saveProduct = function () {
$scope.product.$save(function(data){});
}
};
}]);
// some markup from template
<div class="form-group ">
<label class="col-md-2 control-label"
for="inputProductName">Product Name</label>
<div class="col-md-4">
<input class="form-control"
id="inputProductName"
name="inputProductName"
type="text"
placeholder="Product Name (required)"
required
ng-model="product.productName" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="inputProductCode">Product Code</label>
<div class="col-md-4">
<input class="form-control"
id="inputProductCode"
name="inputProductCode"
type="text" ng-model="product.productCode">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="inputAvailabilityDate">Availability</label>
<div class="col-md-4">
<div class="form-control">
{{product.releaseDate}}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="inputDescription">Description</label>
<div class="col-md-4">
<textarea class="form-control"
id="inputDescription"
name="inputDescription"
placeholder="Description"
rows="3" ng-model="product.description"></textarea>
</div>
<br />
</div>
<div class="form-group">
<div class="col-md-4 col-md-offset-2">
<span>
<button class="btn btn-primary"
style="width:80px;margin-right:10px" ng-click="saveProduct()">
Save
</button>
</span>

to use $save() without calling get what i do is here:
productResource.save($scope.product, function(data) {
});
Thanks #TzachOvadia for providing me a clue :)

Try this:
$scope.product = productResource.get({ id: $scope.num });
$scope.saveProduct = function () {
$scope.product.$save(function (response) {...});
}

Related

Node.js Sails html data using "POST" method can not pass to controller

I am new to MVC.
When I want to pass the form data from ejs file to controller, it does not work.
Create.ejs file
<!--create.ejs-->
<h2 class="col-sm-offset-1">Person Create form</h2>
<form action="/person/create" method="POST" class="form-horizontal">
<div class="form-group">
<label class="control-label col-sm-2">Name: </label>
<div class="col-sm-8">
<input class="form-control" name="Person[name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Age: </label>
<div class="col-sm-8">
<input class="form-control" name="Person[age]" type="number"
min="0" max="120">
</div>
</div>
<button class="btn btn-default col-sm-offset-2" type="submit" value="ADD">Submit</button>
PersonController.js
module.exports = {
create: function(req, res) {
if (req.method == "POST") {
Person.create(req.body.Person).exec( function(err, model) {
return res.send("Successfully Created!");
});
} else {
return res.view('person/create');
}
},
The result is that it cant get inside the (req.method == "POST") condition.
Give me 404 error.
A 404 is a not found result.
When POSTing ensure you are targeting your Controller functions try:
'POST /person/create': 'person/PersonController.create',
Though why do you have a subfolder named person when you are using a controller?
Using Actions
In Sails v1.0 you would separate your controller functions into more manageable actions. A sub folder api/controllers/person makes more sense now.
Your routes.js file would read 'POST /person/create': {action: 'person/create'},
For simplicity I have removed req.body.Person as an array...
<form action="/person/create" method="POST" class="form-horizontal">
<input type="hidden" name="_csrf" value="<%= _csrf %>" />
<div class="form-group">
<label class="control-label col-sm-2">Full Name: </label>
<div class="col-sm-8">
<input class="form-control" name="fullName" placeholder="John Johnson" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Age: </label>
<div class="col-sm-8">
<input class="form-control" name="age" type="number" min="0" max="120">
</div>
</div>
<button class="btn btn-default col-sm-offset-2" type="submit" value="ADD">Submit</button>
</form>
then your async function would be like...
module.exports = {
friendlyName: 'Create Person.',
description: 'Creating a new person.',
exits: {
success: {
description: 'Person Created successfully.',
viewTemplatePath: 'person/review',
}
},
fn: async function (inputs, exits) {
if (!this.req.me) throw {redirect: '/'};
let params = this.req.allParams();
let person = await Person.create(params).fetch();
return exits.success({person:person});
}
}
Like #Tejashwi suggested you need to change your route to a POST.
'POST /api/v1/create': { action: 'create/person-create-form' },

AngularJS 1.6.8: Form data not submitting and so hence unable to save it to localStorage

I have a contact form. On submission, it displays a success message and it should store that data to $localStorage.
But, Form data not is not submitting as I do not see submitted form data in response under network in dev tools and hence I am unable to save it to $localStorage.
below is the code for respective files.
link to plunker
contact.html
<div ngController="contactController as vm">
<div class="heading text-center">
<h1>Contact Us</h1>
</div>
<div>
<form class="needs-validation" id="contactForm" novalidate method="post" name="vm.contactForm" ng-submit="saveform()">
<div class="form-group row">
<label for="validationTooltip01" class="col-sm-2 col-form-label">Name</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipName" placeholder="Name" ng-model="vm.name" required>
<div class="invalid-tooltip">
Please enter your full name.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltipEmail" class="col-sm-2 col-form-label">Email</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="validationTooltipUsernamePrepend">#</span>
</div>
<input type="email" class="form-control" id="validationTooltipEmail" placeholder="Email"
aria-describedby="validationTooltipUsernamePrepend" ng-model="vm.email" required>
<div class="invalid-tooltip">
Please choose a valid email.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltip03" class="col-sm-2 col-form-label">Query</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipQuery" ng-model="vm.query" placeholder="Query" required>
<div class="invalid-tooltip">
Please write your Query.
</div>
</div>
</div>
<div class="btn-group offset-md-5">
<button class="btn btn-primary" type="submit">Submit</button>
<button class="btn btn-default" type="button" id="homebtn" ng-click="navigate ('home')">Home</button>
</div>
</form>
<span data-ng-bind="Message" ng-hide="hideMessage" class="sucessMsg"></span>
</div>
</div
contact.component.js
angular.module('myApp')
.component('contactComponent', {
restrict: 'E',
$scope:{},
templateUrl:'contact/contact.html',
controller: contactController,
controllerAs: 'vm',
factory:'userService',
$rootscope:{}
});
function contactController($scope, $state,userService) {
var vm = this;
vm.saveform = function(){
var name= vm.name;
var email= vm.email;
var query= vm.query;
console.log(name);
console.log(email);
console.log(query);
$scope.hideMessage = false;
$scope.Message = "Your query has been successfully submitted.";
$scope.user = userService;
};
$scope.navigate = function(home){
$state.go(home)
};
};
//localStorage code
function userService(saveform) {
var service = {
model: {
name: '',
email: '',
query:''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (sessionStorage.restorestate == "true") {
$rootScope.$broadcast('restorestate'); //let everything know we need to restore state
sessionStorage.restorestate = false;
}
});
//let everthing know that we need to save state now.
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
};
There are no errors in console.

Module AngularJS loading-bar doesn't work

I am trying nodeJS, SailsJS & Angular. I want use this loading bar:
http://chieffancypants.github.io/angular-loading-bar/
https://github.com/chieffancypants/angular-loading-bar
I read the loading bar handle http request are automatically.
so i do this :
npm install angular-loading-bar.
I put the jss and css in assets.
Here my LoginModule :
var LoginModule = angular.module('LoginModule', ['angular-loading-bar']);
And my LoginController :
angular.module('LoginModule')
.controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', 'cfpLoadingBar'];
function LoginController($scope, $http, cfpLoadingBar) {
// Get CSRF token and set as header
$http.defaults.headers.post['X-CSRF-Token'] = document.getElementsByName('_csrf')[0].value;
$scope.submitLoginForm = function() {
$scope.start();
$http.post('/login', {
identifiant: $scope.login.identifiant,
password: $scope.login.password
})
.then(function onSuccess() {
window.location = '/home/';
})
.catch(function onError(response) {
console.log(response);
})
}
$scope.start = function() {
cfpLoadingBar.start();
};
$scope.complete = function() {
cfpLoadingBar.complete();
};
}
But when i login on my form :
<div class="container-fluid" ng-app="LoginModule" ng-controller="LoginController" ng-cloak>
<div class=" col-lg-offset-4 col-lg-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Connexion</h3>
</div>
<div class="panel-body">
<h5 class="col-lg-12" style="text-align: center">Admin !</h5>
<form ng-submit="submitLoginForm()" class="col-lg-offset-3 col-lg-6 form-group" name="loginForm">
<input type="text" class="form-control" id="inputLogin" name="inputLogin" placeholder="Identifiant" ng-model="login.identifiant">
<input type="password" class="form-control" id="inputPassword" name="inputPassword" placeholder="Mot de passe" ng-model="login.password">
<br>
<button type="submit" class="btn btn-primary" style="float: right">Connexion</button>
<input type="hidden" name="_csrf" value="<%= _csrf %>">
</form>
</div>
</div>
</div>
</div>
I don't see the loading bar when i submit the form (form working) :( why ? Also when i try to load ngAnimate in LoginModule i have an error
I tried also the function start() on element HTML but nothing..
You Must include angular-animate.min.js to make it work
as also include in git repository example. when I removed this line
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-animate.min.js"></script>
it stopped working please make sure you include animation file. that's why ngAnimate also giving error

Part's of form not being rendered - AngularJS

I can't seem to find why the "start" and "finish" part of my form isn't being rendered. This is the first time I've ever worked with AngularJS, and after following quite a few tuts online, I used to yo meanjs generator with the articles example. I then took the articles example and tried to port it over to this scheduling thing. It really doesn't matter though, I just want to know why the last two inputs in the form aren't being rendered in my view.
Any help is much appreciated
Here's the code for my view:
<section data-ng-controller="SchedulesController">
<div class="page-header">
<h1>New Schedule</h1>
</div>
<div class="col-md-12">
<form name="scheduleForm" class="form-horizontal" data-ng-submit="create()" novalidate>
<fieldset>
<div class="form-group" ng-class="{ "has-error": scheduleForm.title.$dirty && scheduleForm.title.$invalid }">
<label class="control-label" for="title">Title</label>
<div class="controls">
<input name="title" type="text" data-ng-model="title" id="title" class="form-control" placeholder="Title" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="content">Content</label>
<div class="controls">
<textarea name="content" data-ng-model="content" id="content" class="form-control" cols="30" rows="10" placeholder="Content"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label" for="start">Start</label>
<div class="controls">
<input name="finish" value="" type="date" data-ng-model="start" class="form-control" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-default">
</div>
<div data-ng-show="error" class="text-danger">
<strong data-ng-bind="error"></strong>
</div>
</fieldset>
</form>
</div>
</section>
Here's the code for my controller:
'use strict';
angular.module('schedules').controller('SchedulesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Schedules',
function($scope, $stateParams, $location, Authentication, Schedules) {
$scope.authentication = Authentication;
$scope.create = function() {
var schedule = new Schedules({
title: this.title,
content: this.content,
start: this.start,
finish: this.finish
});
schedule.$save(function(response) {
$location.path('schedules/' + response._id);
console.log('hola!');
$scope.title = '';
$scope.content = '';
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.remove = function(schedule) {
if (schedule) {
schedule.$remove();
for (var i in $scope.schedules) {
if ($scope.schedules[i] === schedule) {
$scope.schedules.splice(i, 1);
}
}
} else {
$scope.schedule.$remove(function() {
$location.path('schedules');
});
}
};
$scope.update = function() {
var schedule = $scope.schedule;
schedule.$update(function() {
$location.path('schedules/' + schedule._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.find = function() {
$scope.schedules = Schedules.query();
};
$scope.findOne = function() {
$scope.schedule = Schedules.get({
scheduleId: $stateParams.scheduleId
});
};
}
]);
Um... Well guys.... I don't know WHY this worked, and everything in me tells me this wasn't the problem, BUT:
Notice line
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
The "," was a mistake (I wrote a script that ported everything from articles into schedule, maintining code structure and just changing all mentions of [Aa]rticle{s} -> [Ss]chedule{s}, and this was left over in that (for some reason, don't know where it came in). Anyway, I deleted the comment and ran grunt build && grunt test && grunt and it worked. I'm now getting the correct render.

Angular js not retrieving value by id's for dropdowns

I have an angular app with the following function:
$scope.search= function(){
var lname = document.getElementById("lastname").value;
var campus2 = document.getElementById("campusid").value;
StudentSearchService.getStudents(lname, campus2, function(data){
if(data!=null){
$scope.students = data;
}
});
}
and in the html page, I have the following 2 fields:
<div class="form-group col-lg-4 col-md-4">
<label for="lastname"> Last Name: </label>
<input type="text" id="lastname" placeholder="Last Name" class="form-control" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus"> Campus:</label>
<select class="form-control" id="campusid" ng-model="newcampus" ng-options="camp.name for camp in campus" >
<option value="">ALL - District</option>
</select>
</div>
When i click to Search, the value for the lname is being retrieved just fine but the value from the dropdown campus2 is not being being initialized. Thus the call to the service is not being made properly.
Where am I going wrong?
First, it is not necessary to pick values from DOM elements if you are using Angular. It is way more easier to bind variables and use the variables themselves. I have created your example in JSFiddle: http://jsfiddle.net/rmadhuram/1n14eqfw/2/
HTML:
<div ng-app="app" ng-controller="FormController">
<div class="form-group col-lg-4 col-md-4">
<label for="lastname">Last Name:</label>
<input type="text" id="lastname" ng-model="lastName" placeholder="Last Name" class="form-control" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus">Campus:</label>
<select class="form-control" id="campusid" ng-model="newcampus" ng-options="camp.name for camp in campus">
</select>
</div>
<button ng-click='search()'>Search</button>
</div>
JavaScript:
angular.module('app', [])
.controller('FormController', ['$scope', function ($scope) {
$scope.campus = [
{ name: 'campus 1' },
{ name: 'campus 2' }
];
$scope.newcampus = $scope.campus[0];
$scope.lastName = '';
$scope.search = function() {
alert('Name: ' + $scope.lastName + ' Campus: ' + $scope.newcampus.name);
};
}]);
Hope this helps!
The biggest place you are going wrong is by trying to access values directly from the DOM inside your Angular controller, rather than relying on Angular to bind properties on the scope to your inputs and handle all of that for you.
I have made a version in Plunkr that demonstrates the "Angular way" of approaching this.
The guts of the controller is:
app.controller('MainCtrl', function($scope, StudentSearchService) {
$scope.campus = [
{name: "Campus 1"},
{name: "Campus 2"}
];
$scope.searchParams = {
lastName: "",
campus: null
};
$scope.search = function() {
StudentSearchService.getStudents($scope.searchParams.lastName,
$scope.searchParams.campus.name,
function(data) {
if (data !== null) {
$scope.students = data;
}
});
}
});
And then your markup becomes:
<div class="form-group col-lg-4 col-md-4">
<label for="lastname">Last Name:</label>
<input type="text" id="lastname" placeholder="Last Name" class="form-control" ng-model="searchParams.lastName" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus">Campus:</label>
<select class="form-control" id="campusid" ng-model="searchParams.campus" ng-options="camp.name for camp in campus">
<option value="">ALL - District</option>
</select>
</div>
Note the use of ng-model to bind the inputs to scope properties. Also note there is no DOM access code in the controller. This makes it easier to test, and allows you to test your controller without any DOM at all. That is the core philosophy Angular is based around.

Categories

Resources