ng-file-upload within ngResource ng-multiple progress - angularjs

I have no clue how to dispatch multiple files into one server hit using the ngResource service module.
Below shows passing one file in the callback - that works.
However, if all the files are passed in one call to o.Upload(loParams.files...), Fiddler sees the file count correctly but each hit is missing the data of the file upload.
Then there is the entire seperate issue of showing $progress.
Has anyone besides me played around with this and gotten it working?
var o = $resource('myResource',{}, (
'Upload': {url: 'fileUpload',
method: 'POST',
isArray: false,
transformRequest: formDataObject,
head
});
return {
Upload: function (loParams, dataCallback, errorCallback) {
var laResponse = [];
for (var i = 0; i < loParams.files.length; i++) {
// copy parameters than add the file before uploading
var loFileUpload = angular.copy(loParams)
loFileUpload.files = loParams.files[i];
oDBC.Upload(loFileUpload, function (response) {
laResponse.push(response);
}, function (error) {
errorCallback(error);
});
};
}
Angular.Resource
GitHub :: ng-file-upload

Related

AngularJS get value from API only if not already set

I have service to get some data from API and serve them to application.
Simple function like this:
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
return _this.$http(req);
}
In some other place I have:
determineHostingEnv() {
var _this = this;
this.$env.getEnvironmentStatus()
.then(function(response){
_this.EnvHositng = response.data.cloud_hosted;
}, function(error) {
});
}
If I need the same information in other place (other controller), I would need to call api again.
How can I make getEnvironmentStatus() function to call API only once and store data in local variable, so it can serve that variable next time it is asked for it, instead of calling API?
Also, what if that value will get requested a few times before the first API will return value? Can I prevent calling that API a few times?
One can cache the promise:
httpPromiseCache = null;
getEnvironmentStatus() {
var _this = this;
var req = {
method: "GET",
url: "/api/system/hosting",
headers: {},
data: {}
}
if (!_this.httpPromiseCache) _this.httpPromiseCache = _this.$http(req);
return _this.httpPromiseCache;
}
The service will only execute the HTTP request once.

Multiple GET requests in Angularjs

I want to make multiple ajax calls from different urls in football-data.org
API.
Here's my code sample:
angular.module('liveFootball', ['ionic'])
.constant('urls', {
BASE: 'http://api.football-data.org/',
BASE_API: 'http://api.football-data.org/v1/soccerseasons/',
TEAM_URL: 'http://api.football-data.org/v1/teams',
HEAD: {
'X-Auth-Token': 'e7486677a2dd4260b7aeb8a464749e80'
}
});
getAllFixtures: function(leagueID){
var getAllFixtures = {
method: 'GET',
url: urls.BASE + "fixtures?timeFrame=n14",
headers: urls.HEAD
}
return $http(getAllFixtures);
},
Is there a way I can include another url in this call?
Thanks.
It's not possible to have more than one url field in the $http config object, but you can send the three requests and use Promise.all() $q.all to await their responses. The response will be a promise which when you .then() will have an array containing all the responses.
getAllFixtures: function(leagueID){
var sources = [
urls.BASE,
urls.BASE_API,
urls.TEAM_URL
];
var promises = [];
for(var i=0; i<sources.length; i++){
promises.push($http({
method: 'GET',
url: sources[i] + "fixtures?timeFrame=n14",
headers: urls.HEAD
}));
}
return ̶P̶r̶o̶m̶i̶s̶e̶.̶a̶l̶l̶ $q.all(promises);
}
There is no way you can include another url , you have to call it again. You can use $q.all in angular to make multiple request at once.
For example:
var request = [getAllFixtures('10'), getAllFixtures('11)];
$q.all(request).then(function (value) {
},function(err){
}

Render remote PNG image in AngularJS

I am developing an AngularJS application which displays a PNG image retrieved from a server.
If I put the URL (see below) in the browser I can see the image just fine. However, if I want to retrieve such image from my Angular application I cannot manage to display it (although I do receive the data!).
The JS code is the following:
$scope.receivedImage = null;
var url = 'https://subdomain.mydomain.uk/img?latitude=55.57&longitude=-5.16&extent=2000';
$http(
{
method: 'GET',
url: url,
headers: {
Accept: 'image/png'
}
}
).then(
function successCallback(response) {
var data = response.data;
$scope.receivedImage = data;
},
function errorCallback(response) {
console.error(response);
}
);
The problem is that I cannot see the image that is retrieved. To understand better the situation I put in the HTML page the following code:
<div ng-show="receivedImage">
<pre>{{receivedImage}}</pre>
<img data-ng-src="{{receivedImage}}" />
<img data-ng-src="data:image/png;{{receivedImage}}" />
</div>
The '' shows something like
�PNG IHDR�R9�%IDATx��̱ ������ �2��'��j�Z�V��w����LxIEND�B`�
The first '' does not show anything.
The second '' shows an image icon and throws in console an error:
GET
data:image/png;%EF%BF%BDPNG%1A%00%00%00IHDR%00%00%00%1E%00%00%00%1E%08%02%0…%BD%EF%BF%BD%EF%BF%BD%EF%BF%BDL%0E%17x%00%00%00%00IEND%EF%BF%BDB`%EF%BF%BD
net::ERR_INVALID_URL
How can I render this image correctly?
Try setting the ng-src attribute to a variable that is the url.
$scope.url = 'https://subdomain.mydomain.uk/img?latitude=55.57&longitude=-5.16&extent=2000';
and in the markup
<img ng-src="{{url}}" />
If the url is unprotected then the approach from Anthony helps a lot. For my use-case where the URL was protected i had to go with the below approach. In this case i had to inject the authentication headers by overriding angular's http authentication interceptors for accessing the protected URL.
// http call inside a service under a function named getImage()
$http(
{
method: 'GET',
url: 'YOUR_PROTECTED_RESOURCE_URL',
// This is required for getting your data as buffer array
{
responseType: 'arraybuffer'
}
}
).then(
function successCallback(response) {
return response;
},
function errorCallback(response) {
console.error(response);
}
);
Inside your controller or directive the data that comes from the above call has to be handled like so:
// Function to get the image from the server
var handleImage = function(){
MyHttpService.getImage()
.then(function(response){
// Can be used within ng-src fro displaying image
$scope.receivedImage = 'data:image/png;base64,'+_arrayBufferToBase64(response);
}, function(error){
console.error(error);
});
};
// Convert the buffer to base64
var _arrayBufferToBase64 = function( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
console.log(len);
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
};
Hope this helps someone who is trying to access the resource from a protected resource URI.

Angular chaining promises from foreach loop

I have an array of photo files that needed to upload to Azure Cloud Storage, and i using foreach loop to call upload as below:
$scope.savetemplate = function () {
var imagePathsArray = [];
$scope.filesimage = [];
$scope.filesimage.push($scope.file1);
$scope.filesimage.push($scope.file2);
$scope.filesimage.push($scope.file3);
for (var i in $scope.filesimage) {
$scope.upload($scope.filesimage[i]);
}
$scope.data.Images = imagePathsArray ;
$http({
//after finish uploads i need to post the paths
//of all images to save into database
})
};
$scope.upload = function (file) {
Upload.upload({
url: '/uploadImage',
data: { file: file }
}).then(function (resp) {
imagePathsArray.push(resp.data);
})
};
resp.data returns azure storage path and i need to push the paths into the imagePathsArray
How can i uses Angular Promise to wait for upload all the files finished and all the paths are stored in the imagePathsArray so i can proceed with
$scope.data.Images = imagePathsArray ;
so that i can get the paths in the array and perform $http post?
You can do that with $q.all.
var promises = [];
for (var i in $scope.filesimage) {
promises.push(upload($scope.filesimage[i]));
}
$q.all(promises).then(function() {
$scope.data.Images = imagePathsArray ;
$http.post({
//after finish uploads i need to post the paths
//of all images to save into database
});
});
function upload(file) {
return Upload.upload({
url: '/uploadImage',
data: { file: file }
}).then(function (resp) {
imagePathsArray.push(resp.data);
})
};
In the success callback of the upload function, after pushing the path:
imagePathsArray.push(resp.data);
if(imagePathsArray.length == $scope.filesimage.length){
pushtoDatabase();
}
Inside pushtoDatabase call the $http({ .... });
NOTE : You might like to consider the probability of the upload getting failed. In that case you can work-around using a counter of failed files say failCounter , and then inside the if check for the condition
if ((imagePathsArray.length + failCounter) == $scope.filesimage.length){....}

Angular js api url in loop

$http({method: 'GET', url: '/xxx/xxx/xas'}).success(function(data) {
$scope.website = data.websites;
});
$http({method: 'GET',url: '/xx/xasxxx?websiteId='+$scope.website.websiteId}).success(function(data) {
$scope.onlinedata1 = data.coupons;
});
I try to get websiteID from top url and pass that id in to 2nd url .my json data structure
"websites":[{
"websiteName":"Flipkart",
"websiteId":"1",
},
{
"websiteName":"asas",
"websiteId":"5",
}]
Try to pass every id one by one. I am using AngularJS v1.2.17.
Move the second HTTP call within the success callback of the first one:
$http({method: 'GET', url: '/xxx/xxx/xas'}).success(function(data) {
$scope.website = data.websites;
for (var i = 0; i < data.websites.length; i++)
{
$http({method: 'GET',url: '/xx/xasxxx?websiteId='+data.websites[i].websiteId}).success(function(data) {
$scope.onlinedata1 = data.coupons;
});
}
});
This can be simplified considering that your requests are GETs:
$http.get('/xxx/xxx/xas')
.then(function(res) {
for (var i = 0; i < res.data.websites.length; i++)
{
$http.get('/xx/xasxxx?websiteId='+res.data.websites[i].websiteId)
.then(function(res) {
$scope.onlinedata1 = res.data.coupons;
});
}
});
Please note that the above will issue one request for each website returned by the API. If you have control over the API you might want to consider accepting multiple website IDs on the second URL resource (/xx/xasxxx?websiteIds=1,5,7,12,56) so as to limit the number of requests issued by the client.
Use $q - service in module ng
A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.

Resources