Here is what i try to do :
Json from "urldatas":
[{ "name" : "John" }]
JS file:
var app = angular.module('app', []);
app.service('service', function($http, $q){
this.getDatas = function () {
var datas = $http.get('urldatas', {cache: false});
return $q.all({datas});
};
app.controller('FirstCtrl', function($scope, service, $http, $timeout) {
var vm = this;
vm.loadData = function () {
var promise = service.getDatas();
promise.then(function (data) {
$scope.datas = data.datas.data;
console.log($scope.datas);
});
};
vm.loadPackages = function () {
var url = "urlPackages" + datas.name;
$http.get(url).then(function (response) {
$scope.MyPackages = response.data;
});
};
So i try to dynamicly change url in $http.get in getPackages, by values from getDatas, but i don't know how to do it. url in console shows "urlPackagesundefinded". Thanks for answers in advance.
$q send multiple requests as an array, not as an object. remove the curly bracket and add a square bracket
var datas = $http.get('urldatas', {cache: false});
return $q.all([datas]);
since you reference the controllerAs remove the scope variables and reference them through vm.
also in then promises response data comes under data property
var promise = service.getDatas();
promise.then(function (response) {
vm.datas = response.data.datas.data;
console.log(vm.datas);
});
Related
I have a service that grabs JSON from a URL and I would like to alter that data but I cant seem to do it. Right now I change this in the controller but this seems messy with the scope not reaching places I would like.
//SERVICE
app.service("servers", function ($http, $q)
{
// Grab json
var deferred = $q.defer();
$http.get('http://www.mocky.io/v2/58bea87e260000c318f07bfd').then(function (data)
{
deferred.resolve(data);
});
this.getItems = function ()
{
return deferred.promise;
}
})
// CONTROLLER
.controller("AppCtrl", function ($scope, servers, geoIP) {
var promise = servers.getItems();
promise.then(function (data)
{
$scope.items = data.data.items;
});
$scope.getSelectedItem = function() {
return servers.selectedItem;
}
$scope.selectServer = function(item)
{
servers.selectedItem = item;
servers.selectedItem.refactored_match_state = lowerCamelCaseUnderscoreRefactor(servers.selectedItem.session.attributes.match_state);
}
//COMPONENT/TEMPLATES
//dbServerTable
<tr data-ng-repeat="item in items | filter:search | orderBy:'name'" data-ng-click="selectServer(item)">
<td>{{item.display_name}}</td>
</tr>
//dbServerInfoSidebar
<li>{{getSelectedItem().refactored_match_state}}</li>
Could anyone show me with code how to alter data in a service that can be used anywhere by any controller that can access that service
The way the service has been coded is an anti-pattern and should be avoided. Refer this link.
Change your service like below and make modifications to the data before you return the data within the .then function.
app.service("servers", function ($http)
{
this.getItems = function ()
{
return $http.get('http://www.mocky.io/v2/58bea87e260000c318f07bfd')
.then(function (data)
{
// **** Modify data here ****
return data;
});
}
})
You can use transformResponse property of $http
service;
You can modify your data before resolving the promise
deferred.resolve(data);.
Are you trying to do something like:
app.service("servers", function ($http, $q)
{
this.parseData = data => {
//modify data;
return data;
};
this._request = $http.get('http://www.mocky.io/v2/58bea87e260000c318f07bfd')
.then(this.parseData);
this.getItems = () => this._request;
});
You don't need to use deferred at all. It's unnecessary. $http returns a promise for you. If you want to alter any data, you just need to chain after the request and return the modified data in the chained method.
app.service('services',['$q','$http','$rootScope',function($q,$http,$rootScope){
var obj ={};
obj.getData =function(x){
var defer = $q.defer();
$http.get('http://www.mocky.io/v2/58bea87e260000c318f07bfd')
.then(function(response){
defer.resolve(response);
},function(error){
defer.reject(error);
});
return defer.promise;
}
return obj;
}])
app.controller('ctrl',function($scope,services){
$scope.getItems = function(){
services.getData()
.then(function(response){
$scope.Items=response.data;
},function(error){
console.log(error);
});
}
})
I'm trying get data from db to UI. Url given via provider is getting the data.
Controller in controller DetailsProvider.getDashboardDetails() is getting null.
var appmod = angular.module('project.DetailDashboardController', []);
appmod.controller("DetailDashboardController", ['$rootScope', '$scope', '$state', 'DetailsProvider',function($rootScope, $scope, $state,DetailsProvider) {
console.log("DetailDashboardController --- ");
$scope.DetList= DetailsProvider.getDashboardDetails()
}]);
})(window, window.angular);
provider which will call the list
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
Thanks in advance for any kind of reply!
You should return promise from your service method and do thenable in your controller.
Root Cause : your are returning the newData which will initalized later after completing the ajax call.Before completing it,you are returning the same variable which will be always null.
In provider,
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
and in controller,
$scope.list = function() {
DetailsService.getDashboardDetails(function(data){
varr holdIt = data.data.DList;
});
};
As you can see this is my first time attempting this and I appear to be doing it incorrectly. I just want to take some code, consisting of promises and http requests, and put it in a service before the controller uses it. My goal is to simply clean up the controller so it doesn't contain all of that code.
After logging it in the last step of the controller the object appears as undefined. Also, all the requests are being made successfully. So, it's jumping through all the hoops fine so I'm guessing it must not be returning any value in the service and nothing gets passed on to the subsequent function in the controller. How can I return the 'people' array in the service after the promises have been fulfilled?
var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', function ($scope, $http, dataService) {
var getPeople = function () {
return $http.get('/getpeople');
};
getPeople().then(function (response) {
dataService.compilePeople(response)
})
.then(function (people) {
console.log(people);
$scope.people = people;
});
});
myApp.service('dataService', function ($q, $http) {
this.compilePeople = function (response) {
var people = [];
names = response.data;
grandPromiseArray = [];
names.forEach(function (index) {
var name = index,
count = $q.defer(),
skills = [],
urls = '/getskillsbyname/' + name,
urlc = '/getcountbyname/' + name;
grandPromiseArray.push(
$q.all([$http.get(urls), $http.get(urlc)])
.then(function (response) {
people.push({
name: name,
skills: response[0].data,
count: response[1].data
});
})
);
});
return $q.all(grandPromiseArray).then(function () {
return people
});
}
});
You need to return the promise from compilePeople() in order for the people to be passed into the next .then() handler. so close ;)
getPeople()
.then(function (response) {
//You were missing this return
return dataService.compilePeople(response)
})
.then(function (people) {
console.log(people);
$scope.people = people;
});
I am working on an application in which I am calling a webservice and get a response. I am using that response in 2 different modules. In first module I am using as it is and in second module I am doing some formatting and using it.
I created a service for getting data as follows
angular.module('myApp').factory('getData',function($http, $q, restURLS) {
var getData= {};
getData.getTree = function () {
var deferred = $q.defer();
$http.get(restURLS.getTree).
success(function (data) {
deferred.resolve(data);
}).error(deferred.reject);
return deferred.promise;
};
return getData;
});
for Serving response I created another factory as follows
angular.module('myApp').factory('tree', function($http, $q, restURLS, getData, messages) {
var tree= {};
tree.hierarchy = {};
tree.formattedHierarchy = {};
function formatHierarchy(data) {
//some formatting on data.
tree.formattedHierarchy = data;
}
function callTree() {
getData.getTree()
.then(function (data) {
tree.hierarchy = angular.copy(data);
formatHierarchy(data);
}).catch(function () {
//error
});
}
callTree();
return tree;
});
I want to call webservice only once. if data is loaded then factory('tree') should send the data to controller. Otherwise factory('tree') should call webservice and load data.
you need something to know if you got your tree or not... try this:
(UPDATED)
var myApp = angular.module('myApp', ['ngMockE2E'])
// FAKE HTTP CALL JUST FOR EMULATE
.run(function ($httpBackend) {
var tree = [{
node1: 'abcde'
}, {
node2: 'fghi'
}];
$httpBackend.whenGET('/tree').respond(function (method, url, data) {
return [200, tree, {}];
});
})
// YOUR HTTP SERVICE
.factory('getData', function ($http, $q) {
return {
getTree: function () {
var deferred = $q.defer();
$http.get("/tree").
success(function (data) {
deferred.resolve(data);
}).error(deferred.reject);
return deferred.promise;
}
}
})
.factory('TreeFactory', function ($http, $q, getData) {
var tree = {};
var updated = false;
tree.hierarchy = {};
tree.formattedHierarchy = {};
function formatHierarchy(data) {
//some formatting on data.
tree.formattedHierarchy = data;
}
return {
callTree: function() {
if(!updated){
console.log("making http call");
return getData.getTree().then(function (data) {
tree.hierarchy = angular.copy(data);
formatHierarchy(data);
updated = true;
return tree;
}).
catch (function () {
//error
});
}else{
console.log("tree already loaded");
var deferred = $q.defer();
deferred.resolve(tree);
return deferred.promise;
}
}
};
}).controller("MyCtrl", ['$scope', 'TreeFactory', function ($scope, TreeFactory) {
$scope.updateTree = function(){
TreeFactory.callTree().then(function(data){
$scope.tree = data;
});
};
}]);
HTML
<div ng-app="myApp" ng-controller="MyCtrl" ng-init="updateTree()">tree: {{tree}} <br><button ng-click="updateTree()">UPDATE TREE</button></div>
CHECK THE FIDDLE
I am using the following pattern for my REST API, but vm.listing in my controller is always undefined? Probably my pattern is not right? Is there a different pattern to use here? I don't want to call the .get(..) in my controller code.
.factory("listingsResource", ["$resource", "$q", 'appSettings',
function ($resource, $q, appSettings) {
return $resource(appSettings.serverPath + "api/Listings/:id")
}]);
.factory("editService",
var _listing;
var _getListing = function (listingId) {
_listing = listingsResource.get({
id: listingId
});
}
return {
listing: _listing,
getListing: _getListing
};
Controller Code:
createService.getListing(listingId);
vm.listing = createService.listing;
The problem is that when you call listingsResource.get() it returns a promise. Not the data response.
You have to pass the get() a success callback and then set the listing variable inside this callback. I would do something like this:
.service("listingsService", ["$resource", "$q", 'appSettings',
function ($resource, $q, appSettings) {
var _this = this;
_this.listing = {};
var listingResource = $resource(appSettings.serverPath + "api/Listings/:id");
this.getListing = function(listingId){
listingResource.get({id: listingId},
function (data) {
// Success callback
// Set listing keys-value pairs
// do not do: _this.listing = data
_this.listing.id = data.id;
_this.listing.title = data.title;
},
function(err) {
// error callback
console.log(err);
}
)
}
}
])
This works fine with a factory aswell if you prefer. Then in the controller:
listingService.getListing(listingId);
vm.listing = listingService.listing;