I use this plugin https://github.com/nervgh/angular-file-upload to use multiple file upload in my project.
However, I know that in jQuery File upload plugin you can choose to upload all files in one query, or not.
Is it possible to do this with this plugin ? I found nothing in their docs, and I took a look to the code, it seems not native option.
It is not possible using options or default behaviour, I have edited the file and function uploadAll() :
/**
* Uploads all not uploaded items of queue
*/
FileUploader.prototype.uploadAll = function() {
var items = this.getNotUploadedItems().filter(function(item) {
return !item.isUploading;
});
if (!items.length) return;
var that = this;
angular.forEach(items, function(item) {
item._prepareToUploading();
});
if (this.isHTML5) {
//FILL FormData WITH FILE DETAILS.
var data = new FormData();
var first = true;
angular.forEach(items, function(item) {
console.log(item);
data.append("files", item._file, item.file.name);
// get formData
that._onBeforeUploadItem(item);
// add formData
if (first) {
angular.forEach(item.formData, function(obj) {
angular.forEach(obj, function(value, key) {
data.append(key, value);
});
});
first = false;
}
});
// ADD LISTENERS.
var objXhr = new XMLHttpRequest();
objXhr.addEventListener('load', this.onCompleteAll, false);
objXhr.upload.onprogress = function(event) {
var progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
angular.forEach(items, function(item) {
item._onProgress(progress);
});
};
objXhr.onerror = function() {
var headers = that._parseHeaders(objXhr.getAllResponseHeaders());
var response = that._transformResponse(objXhr.response, headers);
angular.forEach(items, function(item) {
that._onErrorItem(item, response, objXhr.status, headers);
that._onCompleteItem(item, response, objXhr.status, headers);
});
};
objXhr.open("POST", this.url);
angular.forEach(this.headers, function(value, name) {
objXhr.setRequestHeader(name, value);
});
// SEND FILE DETAILS TO THE API.
objXhr.send(data);
} else {
items[0].upload();
}
};
I made a new function UploadAllAtOnce() & is working for me. Thanks to #Vincent Decaux. I've modified some code as below -
FileUploader.prototype.uploadAllAtOnce = function uploadAllAtOnce() {
var items = this.getNotUploadedItems().filter(item => !item.isUploading);
if (!items.length) return;
forEach(items, item => item._prepareToUploading());
var that = this;
forEach(items, function (item) {
return item._prepareToUploading();
});
if (this.isHTML5) {
var sendable = new FormData();
var first = true;
forEach(items, (item) => {
sendable.append(item.alias, item._file, item.file.name);
// get formData
that._onBeforeUploadItem(item);
// add formData
if (first) {
angular.forEach(item.formData, function (obj) {
angular.forEach(obj, function (value, key) {
sendable.append(key, value);
});
});
first = false;
}
});
// ADD LISTENERS.
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', this.onCompleteAll, false);
xhr.upload.onprogress = (event) => {
var progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
angular.forEach(items, function (item) {
item._onProgress(progress);
});
};
xhr.onerror = () => {
var headers = this._parseHeaders(xhr.getAllResponseHeaders());
var response = this._transformResponse(xhr.response, headers);
angular.forEach(items, function (item) {
that._onErrorItem(item, response, xhr.status, headers);
that._onCompleteItem(item, response, xhr.status, headers);
});
};
xhr.onload = () => {
var headers = this._parseHeaders(xhr.getAllResponseHeaders());
var response = this._transformResponse(xhr.response, headers);
angular.forEach(items, function (item) {
var gist = that._isSuccessCode(xhr.status) ? 'Success' : 'Error';
var method = '_on' + gist + 'Item';
that[method](item, response, xhr.status, headers);
// that._onCompleteItem(item, response, xhr.status, headers);
});
};
xhr.onabort = () => {
var headers = this._parseHeaders(xhr.getAllResponseHeaders());
var response = this._transformResponse(xhr.response, headers);
angular.forEach(items, function (item) {
his._onCancelItem(item, response, xhr.status, headers);
this._onCompleteItem(item, response, xhr.status, headers);
});
};
xhr.open("POST", this.url, true);
forEach(this.headers, (value, name) => {
xhr.setRequestHeader(name, value);
});
xhr.send(sendable);
} else {
items[0].upload();
}
};
Related
I want to cache response from "POST" request in angularJS.
In Ajax, "cache = true" works only for GET request. How can we achieve it using cacheFactory or any other method.
Here below I want to cache 'viewDetails' data for particular id and not call ajax(in turn backend) again and again on click.
Also, How do I bust the cache everytime(cachefactory), is it only for particular session and release cache itself once session is closed or need to bust it explicitly.
Any help is appreciated.
service.js.
import {moduleName} from "../config/constants";
const serviceName = `${moduleName}_dataService`;
angular.module(moduleName).factory(serviceName, service);
service.$inject = ['$q', '$http'];
function service($q, $http) {
return {
getDetailsData: getDetailsData
};
function getDetailsData(payload) {
const def = $q.defer();
const promise = $http({
method: 'POST',
url: '/order/gentrular-db/viewDetails',
data: payload
});
promise.then(
(response) => {
if (typeof response.data === 'undefined' || response.data === null) {
def.reject("Empty response body");
return;
}
def.resolve(response.data);
},
(error) => {
def.reject(error.status);
});
return def.promise;
}
}
export {serviceName};
controller.js:
import {serviceName as dataServiceName} from "../../services/detailsDataService";
controller.$inject = ['$scope', dataServiceName];
function controller($scope, dataService) {
const $ctrl = this;
// Input binding
$ctrl.productId = null;
$ctrl.onClickClose = null;
// Local binding
$ctrl.$onInit = onInit;
$ctrl.ready = false;
$ctrl.productDetailSection = null;
$ctrl.clinicalSection = null;
$ctrl.importantInformationSection = null;
$ctrl.close = close;
function onInit() {
const promise = dataService.getDetailsData(buildPayload());
promise.then((data) => {
$ctrl.productDetailSection = data.productDetailSection;
$ctrl.clinicalSection = data.clinicalSection;
$ctrl.importantInformationSection = data.impInformationSec;
$ctrl.ready = true;
});
}
function buildPayload() {
return {
productType: "hortiz",
productId: $ctrl.productId
};
}
function close() {
if (angular.isFunction($ctrl.onClickClose)) {
$ctrl.onClickClose();
}
}
}
export {controller};
I was able to cache response using cacheFactory. Here is my working code.
import {moduleName} from "../config/constants";
const serviceName = `${moduleName}_dataService`;
angular.module(moduleName).factory(serviceName, service);
service.$inject = ['$q', '$http', '$cacheFactory'];
function service($q, $http, $cacheFactory) {
return {
getDetailsData: getDetailsData
};
function getDetailsData(payload,productId) {
var cache = $cacheFactory.get('detailsDataCache') || $cacheFactory('detailsDataCache');
var cacheId = productId;
var cachedData = cache.get(cacheId);
const def = $q.defer();
if (!cachedData) {
const promise = $http({
method: 'POST',
url: '/order/gentrular-db/viewDetails',
data: payload
});
promise.then(
(response) => {
if (typeof response.data === 'undefined' || response.data === null) {
def.reject("Empty response body");
return;
}
cache.put(cacheId, response.data);
def.resolve(response.data);
},
(error) => {
def.reject(error.status);
});
}else {
return $q.when(cachedData);
}
return def.promise;
}
}
export {serviceName};
I have been trying to set the responseType to 'arrayBuffer' in the following code, but I keep getting Failed to load pdf document
var resource = ApiService.getResource('/cases/report');
resource.get({caseId: self.CaseID,responseType:'arraybuffer'},function(data){
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
I have tried putting {responseType: 'arraybuffer'} in the getResource method along with a various other places in the get method, but I get the error Failed to Load Pdf Document
I also tried adding it here like:
var resource = $resource('url', {},{responseType: 'arraybuffer'});
but this doesn't work as well
Full code:
function getResource(endpoint) {
var resource = $resource(endpoint, null);
return wrapActions(resource);
}
function wrapActions(resource) {
var wrappedResource = resource;
for (var i = 0; i < self.actions.length; i++) {
self.wrapAction(wrappedResource, self.actions[i]);
}
// return modified copy of resource
return wrappedResource;
}
function wrapAction(resource, action) {
// copy original action
resource['_' + action] = resource[action];
// create new action wrapping the original and sending token
resource[action] = function (data, success, error) {
data = data || {};
return resource['_' + action](
angular.extend({}, data),
function (response) {
handleSuccess(response, success);
},
function (response) {
handleError(response, error);
}
);
};
}
function handleSuccess(response, callback) {
if (callback) {
callback(response);
}
}
function handleError(response, callback) {
if (typeof response.status !== 'undefined') {
switch (response.status) {
case '403' :
case 403 :
case '401' :
case 401 :
handle401();
return;
}
}
if (callback) {
callback(response);
}
}
function handle401() {
if ($state.current.name != 'login') {
AuthService.setRedirect($state.current.name, $stateParams);
}
AuthService.logout();
$state.go('login');
}
}
use $cordovaFileTransfer to upload images,but it stop at 99%, $_FILES is empty in PHP;
and i get evt object.
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"16656","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"33040","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"98576","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"131344","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"147728","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"164112","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"180496","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"213264","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"229648","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"65808","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"82192","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"114960","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"295184","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"262416","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"311568","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"327952","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"344336","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"360720","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"377104","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"409872","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"442640","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"393488","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"426256","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"459024","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"475408","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"491163","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"196880","total":"491176"}
{"bubbles":"false","cancelBubble":"false","cancelable":"false","lengthComputable":"true","loaded":"246032","total":"491176"}
what's wrong with the property loaded;why it increase repeatly;
upload code
$scope.upload = function(imageURI) {
$scope.dangerList[$scope.setting.num][$scope.setting.imageType + '1pic'] = imageURI;
var server = 'http://localhost/test.php';
var dirName = 'check';
var desName = 'test';
var options = {
'httpMethod': 'POST',
'params': {
'dirName': dirName,
'desName': desName
}
};
var promise = $cordovaFileTransfer.upload(server, imageURI, options, true);
promise.then(function(data) {
console.log(data);
}, function(data) {}, function(evt) {
$ionicLoading.show({
template: '<p>upload:' + parseInt(100.0 * evt.loaded / evt.total) + '%</p>',
//duration: 1000,
});
});
return promise;
};
and ngCordova\src\plugins\fileTransfer.js
angular.module('ngCordova.plugins.fileTransfer', [])
.factory('$cordovaFileTransfer', ['$q', '$timeout', function($q, $timeout) {
return {
download: function(source, filePath, options, trustAllHosts) {
var q = $q.defer();
var ft = new FileTransfer();
var uri = (options && options.encodeURI === false) ? source : encodeURI(source);
if (options && options.timeout !== undefined && options.timeout !== null) {
$timeout(function() {
ft.abort();
}, options.timeout);
options.timeout = null;
}
ft.onprogress = function(progress) {
q.notify(progress);
};
q.promise.abort = function() {
ft.abort();
};
ft.download(uri, filePath, q.resolve, q.reject, trustAllHosts, options);
return q.promise;
},
upload: function(server, filePath, options, trustAllHosts) {
var q = $q.defer();
var ft = new FileTransfer();
var uri = (options && options.encodeURI === false) ? server : encodeURI(server);
if (options && options.timeout !== undefined && options.timeout !== null) {
$timeout(function() {
ft.abort();
}, options.timeout);
options.timeout = null;
}
ft.onprogress = function(progress) {
q.notify(progress);
};
q.promise.abort = function() {
ft.abort();
};
ft.upload(filePath, uri, q.resolve, q.reject, options, trustAllHosts);
return q.promise;
}
};
}]);
and push interceptor
.factory('UserInterceptor', function ($q, $rootScope) {
return {
request:function(config){
config.headers = config.headers || {};
config.headers.UID = $rootScope.user.id || 0;
return config;
},
requestError: function(err){
return $q.reject(err);
},
response: function (response) {
return response;
},
};
})
it could work few days ago.
during the time,
add plaform with android#5.1.1 instead of android#4.1.1;
update cordova;
use ionic 1.7.3 now;
and here is the download code,it can works,but will download file twice
$scope.down = function(fname) {
var fileTransfer = new FileTransfer();
var uri = encodeURI($rootScope.rootUrl + fname);
var fileURL = cordova.file.externalRootDirectory + fname;
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log(entry);
},
function(error) {
console.log(error);
},
false, {
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
};
This is actually the response from progress event of cordovaFileTransfer.
On success it'll give response something like this:
Object {bytesSent: 3228135, responseCode: 200, response: "<!-- Served from 80.251.0.59 / test.talia.net, as …imited↵</p>↵↵</td></tr></table>↵↵</body>↵</html>↵", objectId: ""}
But as per the output you are getting,I think the function is getting interrupted by the same method from another instance because your whole file was almost uploaded in the 3rd last line.
"cancelable":"false","lengthComputable":"true","loaded":"491163","total":"491176"}
And then it picked up from some another point.
Please provide the code so I can try to assist you further.
Thank you
I have some Web API that return data.
Now I want to create a custom object based on such data.
The thing is that these http calls are dependent.
Here is the code, as you can see, at getLabMainAndLinesCombined()
there are 4 http calls encapsulated in:
contactsService.getContactPersonsIdNameList()
getLabMainsIdAppIdList()
getAllLabLines()
getAllLabMains()
And lastly there is the generateProperMappings that 'glues' it up.
var generateProperMappings = function (companiesIdName, contactPersonsIdName, labMainsIdAppId, labMains, labLines) {
var result = [];
var i = 0;
while (i < labMains.length) {
var labMain = labMains[i];
var workAppId = labMainsIdAppId.filter(options => options.id === labMain.id)[0].appId;
var companyName = companiesIdName.filter(options => options.id === labMain.companyId)[0].name;
var contactPersonName = contactPersonsIdName.filter(options => options.id === labMain.contactPersonId)[0].fullName;
var associatedLabLines = labLines.filter(options => options.assignedToWork === labMain.id);
var viewDetails = {
work: { id: labMain.id, appId: workAppId },
company: { id: labMain.companyId, name: companyName },
contactPerson: { id: labMain.contactPersonId, fullName: contactPersonName },
workDetails: { created: labMain.dateCreated },
labLinesAssociated: associatedLabLines
}
result.push(viewDetails);
i++;
};
return result;
};
var getLabMainAndLinesCombined = function () {
var deferred = $q.defer();
console.log("Generating view of mains and lines combined");
var companiesIdName = [];
var contactPersonsIdName = [];
var labMainsIdAppId = [];
var labLines = [];
var labMains = [];
var result = [];
contactsService.getCompaniesIdNameList().then(data => {
angular.copy(data, companiesIdName);
contactsService.getContactPersonsIdNameList().then(data => {
angular.copy(data, contactPersonsIdName);
getLabMainsIdAppIdList().then(data => {
angular.copy(data, labMainsIdAppId);
getAllLabLines().then(data => {
angular.copy(data, labLines);
getAllLabMains().then(data => {
angular.copy(data, labMains);
result.push(generateProperMappings(companiesIdName, contactPersonsIdName, labMainsIdAppId, labMains, labLines));
});
});
});
});
});
deferred.resolve(result);
return deferred.promise;
};
The problem is that this function (a Service function) is called from a controller, but the result data is returned before it is really generated...
Here is the call:
var onLabLinesReceived = function (data) {
console.log(data);
angular.copy(data, vm.labLines);
}
labService.getLabMainAndLinesCombined().then(onLabLinesReceived, onError).finally(function () { vm.isBusy -= 1 });
In the debugging # Chrome, it looks like this:
labService.js:53 Generating view of mains and lines combined contactsService.js:27 Getting all companies id name list labLinesTableController.js:35 [] <-- PROBLEM contactsService.js:36 Getting all contacts id name list labService.js:15 Getting all lab mains labService.js:7 Getting all lab lines labService.js:15 Getting all lab mains
Don't resolve your promise until after all of the items you need have been added to results function has finished. Right now what you're code is doing is sending a promise that resolves to an empty list.
var getLabMainAndLinesCombined = function () {
var deferred = $q.defer();
console.log("Generating view of mains and lines combined");
var companiesIdName = [];
var contactPersonsIdName = [];
var labMainsIdAppId = [];
var labLines = [];
var labMains = [];
var result = [];
contactsService.getCompaniesIdNameList().then(data => {
angular.copy(data, companiesIdName);
contactsService.getContactPersonsIdNameList().then(data => {
angular.copy(data, contactPersonsIdName);
getLabMainsIdAppIdList().then(data => {
angular.copy(data, labMainsIdAppId);
getAllLabLines().then(data => {
angular.copy(data, labLines);
getAllLabMains().then(data => {
angular.copy(data, labMains);
result.push(generateProperMappings(companiesIdName, contactPersonsIdName, labMainsIdAppId, labMains, labLines));
});
});
});
});
})
// Resolve your promise here after all the data has been retrieved.
.then(() => {deferred.resolve(result)});
return deferred.promise;
};
I'd strongly recommend you refactor your code for readability.
var getLabMainAndLinesCombined = function () {
var deferred = $q.defer();
console.log("Generating view of mains and lines combined");
var companiesIdName = [];
var contactPersonsIdName = [];
var labMainsIdAppId = [];
var labLines = [];
var labMains = [];
var result = [];
// You can use hanging indentation and have then statements return
// The promises they are meant to sequentially resolve. That way
// the code is much more readable and gives a clearer picture of
// how the function works.
contactsService.getCompaniesIdNameList()
.then(data => {
angular.copy(data, companiesIdName);
return contactsService.getContactPersonsIdNameList()
})
.then(data => {
angular.copy(data, contactPersonsIdName);
return getLabMainsIdAppIdList();
})
.then(data => {
angular.copy(data, labMainsIdAppId);
return getAllLabLines()
})
.then(data => {
angular.copy(data, labLines);
return getAllLabMains();
})
.then(data => {
angular.copy(data, labMains);
result.push(generateProperMappings(companiesIdName, contactPersonsIdName, labMainsIdAppId, labMains, labLines));
})
// Now when promise is complete it will renturn the list
.then(() => { deferred.promise; });
};
return the promise from getLabMainAndLinesCombined function
var getLabMainAndLinesCombined = function () {
console.log("Generating view of mains and lines combined");
var companiesIdName = [];
var contactPersonsIdName = [];
var labMainsIdAppId = [];
var labLines = [];
var labMains = [];
var result = [];
return contactsService.getCompaniesIdNameList().then(data => {
angular.copy(data, companiesIdName);
contactsService.getContactPersonsIdNameList().then(data => {
angular.copy(data, contactPersonsIdName);
getLabMainsIdAppIdList().then(data => {
angular.copy(data, labMainsIdAppId);
getAllLabLines().then(data => {
angular.copy(data, labLines);
getAllLabMains().then(data => {
angular.copy(data, labMains);
result.push(generateProperMappings(companiesIdName, contactPersonsIdName, labMainsIdAppId, labMains, labLines));
});
});
});
});
});
};
I'm trying to make couple of HTTP requests, one inside another, and I'm having a trouble restructuring my JSON object.
I have a factory function, first of all i'm trying to get all the teams, each team has an Id, and then i'm getting all the news for each team with the id related, and putting that news in the first JSON object.
but this is not working !
.factory('teamsFactory', function ($http,CacheFactory,LocaleManager,$q)
{
teams.Getteams= function()
{
var zis=this;
var promise=$http({method:"GET",url:"http://www.myserver/teams"});
promise.then(function(response){
for (var i=0;i<response.data.length;i++) {
zis.getTeamsNews(response.data[i].idTeam).then(function(newsresponse){
response.data[i].news=newsresponse.data;
});
}
},alert('error'));
return promise;
}
teams.getTeamsNews= function(idTeam)
{
var promise=$http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam});
promise.then(null,alert('error'));
return promise;
}
});
I think it's better to push all the $http promises into an array and then use $q.all() to group them together rather than calling them each individually in a loop. Try this:
Note I had to move some of your functions around and create dummy data etc. so you will have to alter it slightly to fit your app.
DEMO
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, teamsFactory) {
$scope.name = 'World';
teamsFactory.Getteams()
.then(function(data){
$scope.teamsData = data;
});
});
app.factory('teamsFactory', function ($http, $q){
var teams = {};
teams.getFavoriteTeamsNews = function(teamId){
return $http
.get('news.json')
.then(function(response){
console.log('gtTeamNews response', response);
return response.data[teamId];
})
}
teams.Getteams = function(){
var zis = this,
httpConfig = {
method : "GET",
url : "teams.json"
};
return $http(httpConfig)
.then(function(response){
var teamId, promise,
requests = [];
for(var i = 0; i <response.data.length; i++){
teamId = response.data[i].idTeam;
promise = teams.getFavoriteTeamsNews(teamId);
requests.push(promise);
}
return $q
.all(requests)
.then(function(responses){
angular.forEach(responses, function(newsresponse, index){
response.data[index].news = newsresponse;
});
return response.data;
});
})
.catch(function(error){
console.log('error', error);
});
}
return teams;
// teams.TeamsNews= function(idTeam){
// return $http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam})
// .catch(function(){
// alert('error')
// });
// }
});
update
You could also re-factor the above to take advantage of promise chaining which makes it much cleaner in my opinion. This should give the same output but is more 'flat', i.e. has less indentation/callback hell:
DEMO2
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, teamsFactory) {
$scope.name = 'World';
teamsFactory.Getteams()
.then(function(data){
$scope.teamsData = data;
});
});
app.factory('teamsFactory', function ($http, $q){
var responseData,
teams = {};
teams.getFavoriteTeamsNews = function(teamId){
return $http
.get('news.json')
.then(function(response){
console.log('gtTeamNews response', response);
return response.data[teamId];
})
}
teams.Getteams = function(){
var zis = this,
httpConfig = {
method : "GET",
url : "teams.json"
};
return $http(httpConfig)
.then(function(response){
var teamId, promise,
requests = [];
responseData = response.data;
for(var i = 0; i < responseData.length; i++){
teamId = responseData[i].idTeam;
promise = teams.getFavoriteTeamsNews(teamId);
requests.push(promise);
}
return $q.all(requests);
})
.then(function(responses){
angular.forEach(responses, function(newsresponse, index){
responseData[index].news = newsresponse;
});
return responseData;
})
.catch(function(error){
console.log('error', error);
});
}
return teams;
});
eventually something like that .. this is raw solution .. could be enhanced with caching ...
var module = angular.module('myapp', []);
module.factory('teamsFactory', function ($http,CacheFactory,LocaleManager,$q)
{
function ExtractTeamFromData(data){
// TODO
console.log("TODO: Exctract teams from data ...");
}
function FindTeamById(teams, tgeamId){
// TODO
console.log("TODO: Find team by id ...");
}
function ExtractNewsFromData(data){
// TODO
console.log("TODO: Exctract news from data ...");
}
var GetTeams= function()
{
var zis=this;
var promise = $http({method:"GET",url:"http://www.myserver/teams"});
var successCallback = function(data, status, headers, config) {
var teams = ExtractTeamFromData(data);
return teams;
};
var errorCallback = function(reason, status, headers, config) {
console.error("Some error occured: " + reason);
return {
'errorMessage': reason
};
}
promise.then(successCallback,errorCallback);
return promise;
}
var GetTeam = function(idTeam)
{
var promise = GetTeams();
var successTeamsCallback = function(teams, status, headers, config) {
return FindTeamById(teams, tgeamId);
};
var errorTeamsCallback = function(reason, status, headers, config) {
console.error("Some error occured: " + reason);
return {
'errorMessage': reason
};
}
promise.then(successTeamsCallback,errorTeamsCallback);
return promise;
}
var GetTeamsNews = function(idTeam){
var promise = GetTeam(idTeam);
var successTeamCallback = function(team, status, headers, config) {
var newsPromise = $http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam});
var successNewsCallback = function(data, status, headers, config) {
var news = ExtractNewsFromData(data);
return news;
};
var errorNewsCallback = function(reason, status, headers, config) {
console.error("Some error occured: " + reason);
return {
'errorMessage': reason
};
}
newsPromise.then(successNewsCallback,errorNewsCallback);
return newsPromise;
};
var errorTeamCallback = function(reason, status, headers, config) {
console.error("Some error occured: " + reason);
return {
'errorMessage': reason
};
}
promise.then(successTeamCallback,errorTeamCallback);
return promise;
}
return {
GetTeams: GetTeams,
GetTeam: GetTeam,
GetTeamsNews: GetTeamsNews
};
});
You need to create a promise of your own, and resolve it when done, this way :
return $q(function(resolve, reject) {
$http({method:"GET",url:"http://www.myserver/teams"}).then(function(response){
var promises = [];
for (var i=0;i<response.data.length;i++) {
promises.push(zis.getFavoriteTeamsNews(response.data[i].idTeam)).then(function(newsresponse){
response.data[i].news=newsresponse.data;
});
}
$q.all(promises).then(function(){
resolve(response);
});
});
for (var i=0;i<response.data.length;i++) {
zis.getFavoriteTeamsNews(response.data[i].idTeam).then(function(newsresponse){
response.data[i].news=newsresponse.data;
})
});