refactoring "factories" into a $resource - angularjs

Hi I have converted a previous function for editing records in an api into the following resource:
app.factory("Wine", function($resource){
return $resource("http://greatwines.8000.com/wines:id", {
//id as a variable
id: "#id"
},
{
update: {
method: "PUT"
}
});
});
I now want to use this by triggering a form with the "wine" records to edit with the following CTA inside the wine ng-repeat for each wine:
Edit Wine
In my controller I pass the "Wine" resource:
app.controller("editWineCtrl", function ($scope, $http, $routeParams, Wine, $location){
Wine.get({ id: $routeParams.id }, function(wine){
$scope.wine = wine;
});
...
However, in spite of the form URL returning the ID:
http://greatwines.8000.com/#/wines/1323
None of the fields i.e. :
div class="margin-top-20">
<input type="text" class="form-control" ng-model="wine.year" />
</div>
<div class="bold margin-top-20">
Grapes
</div>
<div class="margin-top-20">
<input type="text" class="form-control" ng-model="wine.grapes" />
</div>
Are being populated. Am I using the resource int he correct way?

There is a typo in url
wines:id
It should be
wines/:id

Related

Saving User(s) Email Address and Name to Database, Using AngularJS

My UI starts out with two text boxes, one for the users email address and the other for the users Name:
<input type="text" data-ng-model="contact.email_address" placeholder="Email Address" /><br />
<input type="text" data-ng-model="contact.name" placeholder="Name" />
I am leaving it as basic as I can because I have tried many different ways to get this completed and because I am moving from jQuery to AngularJS, I am getting confused on how to get this done.
I need to have a button where, if there needs to be multiple users, they click on this button, and another set of text boxes appear. I can do this, but I do not know how to combine it with the next part. This is what I do to add X amount of users to an array. I wrote the HTML like the following:
<body data-ng-app="controllerAsRecipient">
<div class="form-group" id="ctrl-as-exmpl" data-ng-
controller="SettingsController">
<ul>
<li data-ng-repeat="contact in contacts track by $index">
<input type="text" data-ng-model="contact.email_address" placeholder="Email Address" /><br />
<input type="text" data-ng-model="contact.name" placeholder="Name" />
</li>
<li>
<button data-ng-click="addContact()">Add Recipients</button>
</li>
</ul>
</div>
The AngularJS looks like:
angular.module('controllerAsRecipient', [])
.controller('SettingsController', function ($scope) {
$scope.contacts = [];
$scope.addContact = function() {
$scope.contacts.push({ email_address: '', name: '' })
}
});
Now the part that I am stuck on is inserting the email address/name array, is how to make an AJAX request that will pass this data to the API. The parameter will be the the array of email/name values, however many there are, whether it is one or 50. I can easily do it in jQuery, using $.ajax, but I do not know how to do it in AngularJS, as I have yet to do it.The above works fine, but I am not opposed to tearing it all apart and having it completely different, if there is an easier way to do it. As I said, I can do this in jQuery with ease, but do not know how to do it (yet) in AngularJS. If anyone could help me, I would be grateful. If I need to be more specific, please let me know and I will write a new question. thank you very much in advance.
Try to use $http, inject into your controller, and make the promise call
angular.module('controllerAsRecipient', [])
.controller('SettingsController', function ($scope, $http) {
$scope.contacts = [];
$scope.addContact = function() {
$scope.contacts.push({ email_address: '', name: '' })
};
$scope.sendInfo = function(){
$http({
method: 'POST'
url: 'your url api',
data: contacts
}).then(function(response){
//if response success
}, function(error){
//if error
});
};
});

Angular - Unable to $setValidity (is not a function)

I have an angular app linked to a Rails a backend.
What I want is to handle Rails validation errors with Angular.
Based on differents tutorials, I did this:
edit.html
<div id="Wrapper" ng-controller="EditCtrl"
<div class="row margin-top-100">
<form name="form">
<div>
<!--- FIELD -->
<input class="field" type="text" ng-blur="update()" ng-model="current.title" name="title">
</div>
</form>
</div>
</div>
edit.js
.controller('EditCtrl',
function($scope, $rootScope, $state, $stateParams, $http, CurrentSpot, $filter, Notification, $modal,$compile, $timeout){
$scope.update = function() {
$http.put('/c/'+$scope.current.id.$oid, {c: $scope.current})
.then(function(success) {
$scope.current = success.data;
Notification.success("Great !")
}, function(error) {
console.log(error)
form.title.$setValidity('server', false);
console.log("FORM", form.title)
})
}
})
Which produces this error form.title.$setValidity is not a function in the console when Rails refused the update.
Maybe one more information: console.log("FORM", form) returns:
<input class="field ng-pristine ng-untouched ng-valid ng-not-empty" type="text" ng-blur="update()" ng-model="current.title" name="title" >
but {{form.title}} in the view returns:
{
"$viewValue":"Cc",
"$modelValue":"Cc",
"$validators":{
},
"$asyncValidators":{
},
"$parsers":[
],
"$formatters":[
null
],
"$viewChangeListeners":[
],
"$untouched":true,
"$touched":false,
"$pristine":true,
"$dirty":false,
"$valid":true,
"$invalid":false,
"$error":{
},
"$name":"title",
"$options":null
}
After many hours of reading tutorials and documentations, I'm not able to find where the problem comes from.
Thanks
When you call the function as form.title.$setValidity('server', false);, form return DOM object, not an Angular object with $-named methods.
Angular creates a object in the $scope for the named form.
Check JSFiddle and take a look at the browser console.

angular js search bar, returns only data I entered into search bar

I am trying to enter a country into a search bar, use ng-click or ng-submit to return only the data for the country i entered into the search bar. right now when i submit, i get every country returned and then i can filter to get the country i want. I have all my data in mongolab, i use node js to get my data to my angular js service, then i have an angular js controller that sends data to the view i want. I am using anguler ui router. Here is my service:
angular.module('TravelSite').service('countryService', ['$http', '$q', function($http, $q) {
this.getCountry = function() {
var dfd = $q.defer();
$http({
method: 'GET',
url: '/country'
}).then(function(response) {
console.log(response.data);
dfd.resolve(response.data);
}, function(err) {
console.log('Error: ' + err);
});
return dfd.promise;
};
this.addCountry = function(body) {
var dfd = $q.defer();
$http({
method: 'POST',
url: '/country',
data: body
}).then(function(response){
console.log(response.data);
dfd.resolve(response.data);
}, function(error) {
console.log('error: ' + error);
});
return dfd.promise;
};
}]);
here is my controller:
angular.module('TravelSite').controller('CtrlCountry', function($scope, countryService) {
$scope.addCountry = function(country, cb) {
countryService.addCountry(country).then(function(res) {
});
}
$scope.getCountry = function() {
countryService.getCountry().then(function(dataFromService) {
$scope.countries = dataFromService;
});
}
});
here is my view:
<div>
<div>
<input type="text" ng-model="search.name">
<input type="text" placeholder="name" ng-model="country.name"/>
<input type="text" placeholder="population" ng-model="country.population"/>
<input type="text" placeholder="travel warning" ng-model="country.travel_warning"/>
<input type="text" placeholder="visa" ng-model="country.visa"/>
<input type="text" placeholder="vaccinations" ng-model="country.vaccinations"/>
<button ng-click="addCountry(country)">Create Country</button>
</div>
<form ng-submit="getCountry()">
<input type="text" ng-model="country.name">
<input type="submit" value="Search">
</form>
<button ng-click="addCountry(country)">Create Country</button>
<ul>
<li ng-repeat="country in countries | filter:search">{{country.name}}
{{country.population}} {{country.travel_warning}} {{country.visa}} {{country.vaccinations}}</li>
</ul>
</div>
I have only been coding for about a month, if anyone can help me, i will be extremely grateful.
thanks, and sorry in advance about the terrible looking code.
I'm new to Angular too. :)
I have some code that does exactly the same. I get a lot of info and, then, filter out only what I want.
Whant you can do to filter is to just do some changes on your view.
On your search input box, you can just do this:
<input type='text' ng-model='search'>
Then, on your ng-repeat, you may use:
<li ng-repeat="country in countries | filter: {name: search}">
If you want to filter all the fields, you may use this instead:
<li ng-repeat='country in countries | search'>
Hope it help. :)

Setting REST value to $scope.value on POST is NULL but accepts hard value

I have a simple form that posts to my REST backend. I have a total of 2 fields on the form, but three values I want to populate.
Using the following form, I have users enter in the articletitle and articlesummary
<div ng-controller="pfcPost">
<form ng-submit="createTask()">
<input type="text" ng-model="newTask.articletitle"
placeholder="add new task here">
<input type="text" ng-model="newTask.articlesummary"
placeholder="add summary">
<input type="submit" value="create">
</form>
</div>
However, I also want to set a value in my DB for the articlelink to be the articletitle (later, I will adapt this to be the title without spaces, etc.).
Here is my controller:
pfcControllers.controller('pfcPost', ['$scope', 'pfcArticles', function ($scope, pfcArticles) {
$scope.newTask = new pfcArticles(
{
articletitle: $scope.articletitle,
articlesummary: $scope.articlesummary,
articlelink: $scope.articletitle
});
$scope.createTask = function () {
// call the service
$scope.newTask.$save(function () {
// when saved, reload the list and recreate a new task
});
}
}]);
Currently, it does not post the value of $scope.articletitle to articlelink, but shows it as null
However, if I change it to a hard value, such as follows, it works.
$scope.newTask = new pfcArticles(
{
articletitle: $scope.articletitle,
articlesummary: $scope.articlesummary,
articlelink: "hard value"
});
Here is the backend factory:
var pfcServices = angular.module('pfcServices', ['ngResource'])
pfcServices.factory('pfcArticles', ['$resource', function ($resource) {
return $resource('https://myrestcall.net/articles/:articleID', { articleID: '#id' },
{
'update': { method:'PATCH'}
}
);
}]);
Any clues why it is not taking the scope item as the value? The other values populate without issue.
I have it working via the following:
Inputs:
<div ng-controller="pfcPost">
<form ng-submit="createTask()">
<input type="text" ng-model="articletitle"
placeholder="add new task here">
<input type="text" ng-model="articlesummary"
placeholder="add summary">
<input type="submit" value="create">
</form>
</div>
Controller:
pfcControllers.controller('pfcPost', ['$scope', 'pfcArticles', function ($scope, pfcArticles) {
var articleentry = new pfcArticles;
$scope.createTask = function () {
articleentry.articletitle = $scope.articletitle;
articleentry.articlesummary = $scope.articlesummary;
articleentry.articlelink = $scope.articletitle;
articleentry.$save();
}
}]);

ng-repeat doesn't auto refresh after save

I am trying to post some data via save but cannot see the data in the browser unless i refresh, the todo.id is showing straight away but not the todo.name
<body ng-controller="TodoCtrl">
<div ng-repeat="todo in Todos.record">
<div>{{todo.id}} : {{todo.name }}</div>
</div>
<div>
<input ng-model="todo.name" />
<button ng-click="addItem()">Add Item</button>
</div>
</body>
var app = angular.module("myApp",['ngResource']);
app.factory("Todo",function($resource){
return $resource(
"http://localhost/rest/motors/users?app_name=motors",
{},
{
query: {method: 'GET',isArray: true},
get: {method: 'GET'},
save:{method:'POST'}
}
)
})
app.controller("TodoCtrl", function ($scope, Todo) {
"use strict";
$scope.Todos = Todo.get();
$scope.addItem = function(){
Todo.save($scope.todo, function(data){
$scope.Todos.record.push(data);
$scope.todo={};
});
}
})
If that code sample is representative of your real code, it's likely a problem that the "input" field that references "todo.name" is OUTSIDE of the ng-repeat loop, so that is defining a model property outside of your "Todos.record" list.
adding &fields=* in the api url solved the issue. eg changed
"http://myexample.com/rest/motors/users?app_name=motors"
to
"http://myexample.com/rest/motors/users?app_name=motors&fields=*"
Thanks for help.

Resources