change variable in angularjs factory using $resource - javascript

In my AngularJS app I want a factory with a method to change a variable in the factory itself by using $resource. The code I have written so far is the following:
factories.factory('FooFactory', function ($resource) {
var foo = null;
return {
query: function () {
foo = $resource(baseUrl + '/someUrl/:query', {}, {
query: { method: 'GET', isArray: true }
});
},
getFoo: function () {
return foo;
}
}
});
So when calling FooFactory.query({query: "someString"}); I want the factory to change the value of foo to the value received from the resource.
I need this behaviour because the value of foo is changed by a directive and I need to bind its value to a value in the scope of a controller.
However, the code above doesn't seem to work. What am I doing wrong?

You do not call any method of resource you only initialize it. Try this:
factories.factory('FooFactory', function ($resource) {
var foo = null;
return {
query: function () {
foo = $resource(baseUrl + '/someUrl/:query', {}, {
query: { method: 'GET', isArray: true }
}).query();
},
getFoo: function () {
return foo;
}
}
});

Related

Angularjs - How to implement getters and setters to Data Model?

I'm building a RESTful Webapp with an AngularJS Frontend.
I'm trying to separate the Data - received via JSON - into an Object which can be passed between controllers, following this tutorial:
http://www.webdeveasy.com/angularjs-data-model/
I'm struggling at the point "Sharing a model between controllers ".
My Problem is, that i can't reach the values from inside of the Object, and also not from the controller, which uses the Object. I 'm only able to reach the values with the {{ }} tags in the html template.
HereÅ› the Object:
(function () {
"use strict";
angular
.module('app.admin')
.factory('AdminEventFactory', AdminEventFactory);
/** #ngInject */
function AdminEventFactory($http) {
function AdminEvent(eventData) {
if (eventData) {
this.setData(eventData);
}
};
//AdminEvent Objekt
AdminEvent.prototype = {
setData: function (eventData) {
angular.extend(this, eventData);
},
load: function (id) {
var scope = this;
$http({
method: "GET",
url: "http://docker-backend.test/api/events/" + id
}).then(function mySuccess(response) {
scope.setData(response.data);
}, function myError(response) {
console.log(response);
});
},
//How to reach the values set in the load method via getter here?
getTitle: function(){
console.log(this.setData.title); //undefined
}
};
return AdminEvent;
}
}());
Here's the call from the controller:
(function () {
"use strict";
angular
.module('app.admin')
.controller('Admin.EventsController', AdminEventsController);
/** #ngInject */
function AdminEventsController( [...] , AdminEventFactory) {
[...]
function editEvent($eventId) {
var event = new AdminEventFactory();
event.load($eventId);
console.log(event);
event.getTitle(); //undefined
$scope.event = event;
}
[...]
In the HTML Template could the value be reached:
<!-- "TestTitle" -->
<div>{{ event.title }}</div>
The event logged via console:
AdminEvent {}
description: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
endDate: "2019-05-16T22:00:00+00:00"
id: 62
startDate: "2019-05-15T22:00:00+00:00"
title: "TestTitle"
> __proto__: Object
[...]
I like to reach things like title via getter and setter in the controllers, in the model and not only via template tags {{ }}.
Thank you for your help!
Have the load method return a promise:
load: function (id) {
var scope = this;
return $http({
method: "GET",
url: "http://docker-backend.test/api/events/" + id
}).then(function mySuccess(response) {
scope.setData(response.data);
return response.data
}, function myError(response) {
console.log(response);
throw response;
});
},
In the controller, use the returned promise:
function editEvent($eventId) {
var event = new AdminEventFactory();
var promise = event.load($eventId);
promise.then(function(data) {
console.log(data);
console.log(event);
event.getTitle(); //undefined
});
$scope.event = event;
}
The .then method of the promise waits for the data to arrive from the server before executing the console.log statements.

angular-ui-router function inside controller is not a function

I created a controller inside a state. We usually use this kind of notation for our angular (1.5) components and services with an angular.extend(self, {}).
My problem here is when self.criteria is being initialized, the browser call self.getAgencies() and return an exception :
Error: self.getAgencies is not a function
(function (app) {
'use strict';
app.config(function ($stateProvider) {
$stateProvider.state('app.invoice', {
url: '/invoice'
abstract: true,
template: '<ui-view></ui-view>'
})
.state('app.invoice.list', {
url: '/list?allMyParam',
template: '<invoices criteria="$ctrl.criteria"></invoices>',
controllerAs: '$ctrl',
controller: function ($location) {
var self = this;
angular.extend(self,{
criteria: {
agencies: self.getAgencies()
},
getAgencies: function () {
if ($location.search().agencies) {
return undefined;
} else {
return ['foo', 'blah'];
}
}
});
}
});
});
})(angular.module('module', []));
I put getAgencies() function over the criteria prototype initialization but it did not change anything.
I got out of it by moving getAgencies() outside of angular.extend(self, {}) like this :
var self = this;
var getAgencies = function () {
if ($location.search().agencies) {
return undefined;
} else {
return ['foo', 'blah'];
}
}
angular.extend(self, {
criteria: {
agencies: getAgencies()
}
});
My code is working so it is ok for me but I would like to understand why my self.getAgencies() is not working when this call inside a controller component works well, and make it better if I can.
I'm using angular-ui-router 0.2.18 with angular 1.5.0.
Thank you for your help.
Because when this code is reached
criteria: {
agencies: self.getAgencies()
},
the angular.extend function has not been called yet, and there is no reason why self should contain the getAgencies function.
Why not initialize the agencies afterwards?
angular.extend(self,{
criteria: { },
getAgencies: function () {
if ($location.search().agencies) {
return undefined;
} else {
return ['foo', 'blah'];
}
}
});
self.criteria.agencies = self.getAgencies();
Alternatively, you could use a getter and post-pone calling the function:
angular.extend(self,{
criteria: {
get agencies() {
if (!self._agencies) {
self._agencies = self.getAgencies();
}
return self._agencies;
}
},
getAgencies: ...
});

Is there anyway to create Javascript object with "default function"? AngularJS

As you may know, AngularJS $http service is allowing to call it with/out specific function, for ex:
$http(req).then(function(){...}, function(){...});
$http.get('/someUrl', config).then(successCallback, errorCallback);
I would like to get some more information about the way I can implement it on my factory and generally in JS.
Functions are Objects in JavaScript. This means that you can assign other properties and functions on a function.
function foo(){
//do something
}
foo.bar = function(){
//do something else
}
As it was mentioned above you can implement what you want using Angular's '$resource'. Here is an example of how it can be used:
app.service('testResource', ['$resource', function ($resource) {
var apiBaseUrl = 'http://test-backend/api';
var testResource = $resource(
apiBaseUrl + '/test/'
{},
{
'query': {
method: 'GET',
isArray: true
}
}
);
this.getAll = function () {
return testResource
.query()
.$promise
.then(function (data) {
var tests = [];
angular.forEach(data[0], function (value) {
tests.push(value);
});
return tests;
});
};
}]);
Then inject it in Controller (or wherever) and call it:
testResource.getAll().then(
function (data) {
$scope.tests = data;
}
);
You can also implement other methods such as POST, PUT, DELETE.

Should my factory return an object with helper methods or should I use prototype?

I'm a beginner with angular and I try to understand if I should user a factory like that:
app.factory('FoobarServices', ['$http', function ($http) {
var Foobar = {
// Model
};
return {
getFoobar: function () {
},
setFoobar: function (Foobar) {
},
update: function (foobar) {
},
delete: function (id)
}
};
}]);
Or something like:
app.factory('Fooba', ['$http', function($http) {
function Foobar(foobar) {
// Initialize foobar
};
Foobar.prototype = {
getFoobars: function() {
},
setFoobar: function(foobar) {
},
update: function(foobar) {
},
delete: function(id) {
},
};
return Foobar;
}]);
I'm not sure to understand what's the pros and cons of each pattern, and which one is more suitable for an angular project.
Could you please tell me which one should I use?
It depends on how you want to use your service.
Factory is usually being used to store some constructor from which you can later instantiate some objects.
For example:
app.factory('Client', function () {
function Client (name) {
this.name = name;
}
Client.prototype.sayHello = function () {
console.log('Hello, my name is ' + this.name + '!');
}
return Client;
})
.controller('ClientController', function (Client) {
var bob = new Client('Bob');
})
If your service is singleton, you can register it as service instead of factory and angular will create an instance for you.
Or you can register it as factory but return some object with methods. It is useful when you don't want to deal with context (this) inside your service logic:
app.factory('ClientStorage', function () {
function set () {
// to be implemented
}
function get () {
// to be implemented
}
return {
get: get,
set: set
};
})

How to write a multiple Aync Function within a Service in AngularJS

Im just starting on AngularJS. I'm not sure how to churn this out. I'm trying to include multiple functions within one service. (I hope this is not against bad practice.)
The following is my working code:
myDataService.async().then(function (d) {
$scope.dbCalls = d.d;
});
My Service:
app.factory('myDataService', function ($http) {
// How do you get this bottom line to work?
// this.getAllCalls = function () {
var myService = {
async: function () {
var promise = $http.post('AngularTest.aspx/FetchCalls', { data: {} }).then(function (response) {
console.log(response);
return response.data;
});
return promise;
}
};
return myService;
//}; <--Commented out for clarity
});
Thanks!
you just return an object with properties from the service, then you are able to call those properties as different service methods
like so:
.service('myService', function() {
return {
firstMethod: function() { ... },
secondMethod: function() { ... },
thirdMethod: function() { ... }
}
})
and in the controller/directive
.controller('myCtrl', function(myService) {
myService.firstMethod();
myService.secondMethod();
myService.thirdMethod();
})

Categories