I'm pretty new to angular so here goes. I have an upload avatar and a thumbnail to show the image of the uploaded avatar. My problem is how to update the thumbnail of the newly uploaded avatar. Coz as of right now I would have to refresh the page first before I can see the changes.
Here's some code in my controller:
//get avatar
$scope.userAvatar = function() {
Api.getAvatar($scope.security.currentUser.email)
.then(function(result) {
//success
$scope.avatarImage = result.config.url;
}, function(result) {
//errors
console.log(result);
});
}
//validate avatar then upload avatar
$scope.validateAvatar = function(files) {
var fd = new FormData();
if(files.length > 0)
{
$scope.filesize = files[0].size;
$scope.filemaxsize = 25 * 1024;
$scope.$apply();
//Take the first selected file
fd.append("avatarImage", files[0]);
$scope.uploadAvatar = function() {
Api.uploadAvatar($scope.security.currentUser.email, fd)
.then(function(result) {
console.log(result.data);
//$scope.avatarImage = result.config.url; ////doesn't update the $scope.avatarImage
//$scope.userAvatar(); //doesn't update the $scope.avatarImage
Api.getAvatar($scope.security.currentUser.email)
.then(function(result) {
//success
console.log('uploaded Image');
$scope.avatarImage = result.config.url;
});
}, function(result) {
console.log(result);
})
};
}
};
and on my partials
<div id="show-avatar" class="col-sm-3 col-sm-offset-3">
<img id="avatarbox" ng-src="{{avatarImage}}" >
</div>
On my controller code above I validate the chosen image first if its not more than 25kb I show the upload button. I included the code on how I upload my avatar maybe it may help on my problem.
okay, i solved my own problem with the below code.
$scope.validateAvatar = function(files) {
var fd = new FormData();
if(files.length > 0)
{
$scope.filesize = files[0].size;
$scope.filemaxsize = 25 * 1024;
$scope.avatarImage = '';
//Take the first selected file
fd.append("avatarImage", files[0]);
$scope.uploadAvatar = function() {
Api.uploadAvatar($scope.security.currentUser.email, fd)
.then(function(result) {
$scope.userAvatar();
}, function(result) {
console.log(result);
})
};
$scope.$apply();
}
};
I reset the $scope.avatarImage then assign it again using the $scope.userAvatar();.
Related
I'm using ngCordova File Transfer plugin in an ionic project to download set of images from urls. Here is the code i'm using for that.
// Save a image file in a given directory
$scope.saveImage = function(dir,imgUrl,imageName) {
var url = imgUrl;
var targetPath = cordova.file.dataDirectory+ dir+"/" + imageName;
var trustHosts = true;
var options = {};
// Download the image using cordovafiletransfer plugin
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
$scope.loadedCount ++;
$ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"});
if($scope.loadedCount == $scope.pages.length) {
$ionicLoading.hide();
$scope.showDownloadSuccessAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: "Your magazine successfully downloaded. You can view it on Downloads!"
});
};
$scope.showDownloadSuccessAlert();
}
}, function(err) {
alert(JSON.stringify(err));
}, function (progress) {
if($scope.loadedCount > 80) {
}
});
};
// Download the current magazine
$scope.downloadMagazine = function() {
if($rootScope.user.user_id == undefined) {
$scope.showLoginAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Oops!',
template: "Your must login to download magazines"
});
};
$scope.showLoginAlert();
return;
}
document.addEventListener('deviceready', function () {
var dirName = $rootScope.currentIssue.slug+'_VOL_'+$rootScope.currentIssue.vol+'_ISU_'+$rootScope.currentIssue.issue;
// First create the directory
$cordovaFile.createDir(cordova.file.dataDirectory, dirName, false)
.then(function (success) {
var count = 1;
$scope.loadedCount = 0;
angular.forEach($scope.pages, function(value, key) {
var imgName = count+".png";
$scope.saveImage(dirName,value.link,imgName); // Then save images one by one to the created directory.
count++;
});
}, function (error) {
// Directory already exists means that the magazine is already downloaded.
$scope.showDownloadedAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Why worry!',
template: "Your have already downloaded this magazine. You can view it on downloads"
});
};
$scope.showDownloadedAlert();
});
}, false);
};
})
Problem here is that program try to download everything at once without waiting for previous one to finish. How to wait for one file to finish downloading and then start the other?
Thanks
If you want to do that automatically (you're not the first one : How can I execute array of promises in sequential order?), you could try reducing the list of address to a single Promise that will do the whole chain.
$scope.pages.reduce(function (curr,next) {
return curr.then(function(){
return $scope.saveImage(dirName, curr.link, imgName);
});
}, Promise.resolve()).then(function(result) {
$ionicLoading.show({template : "<ion-spinner class='spinner-energized'></ion-spinner><p> Downloading pages : "+ $scope.loadedCount+" of "+ $scope.pages.length+ "</p><p>Please wait...</p><p><button class=\"button button-block button-positive\">continue in background</button></p>"});
if($scope.loadedCount == $scope.pages.length) {
$ionicLoading.hide();
$scope.showDownloadSuccessAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: "Your magazine successfully downloaded. You can view it on Downloads!"
});
};
$scope.showDownloadSuccessAlert();
}
});
And don't forget to make your saveImage async which returns a promise.
UPDATE:
You will need to remove the then logic from your save method and return the download method call:
return $cordovaFileTransfer.download(url, targetPath, options, trustHosts).promise;
Then you can put your download handler into Promise.resolve()).then. See above.
There's no other way other than chaining your promises. Here's an example:
angular.module('app', [])
.service('fakeDownloadService', function($timeout) {
this.download = (file) => $timeout(() => file, 100);
return this;
})
.run(function($rootScope, $q, fakeDownloadService) {
var listOfFiles = [];
for (var i = 0; i < 10; i++)
listOfFiles.push('file' + i);
$rootScope.log = [];
$rootScope.download = () => {
listOfFiles
.reduce((prev, curr) => {
return prev.then((result) => {
if(result)
$rootScope.log.push(result + ' downloaded');
return fakeDownloadService.download(curr);
});
}, $q.resolve())
.then(() => $rootScope.log.push('all done'));
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<div ng-app="app">
<button ng-click="download()">Start</button>
<div>Log:</div>
<ul>
<li ng-repeat="entry in log track by $index">
{{entry}}
</li>
</ul>
</div>
I'm programming an application
with ionic 1 and firebase 3.
I want to upload an image to the storage of firebase.
When I use html fileupload the image is saved but when i use "cordova.getPictures" the image is not saved.
The code:
.controller("PhotosCtrl",function($scope,$firebaseArray,$firebaseAuth,$firebaseObject, $timeout, $cordovaImagePicker, $ionicPopup){
$scope.upFile = function(){
pickTheImage().then(function(_image) {
processImage(_image);
})
}
function pickTheImage() {
var options = {
maximumImagesCount: 1,
width: 320,
quality: 80
};
return $cordovaImagePicker.getPictures(options).then(function (results) {
return results[0];
})
}
function processImage(_image) {
fetch(_image).then(function (_data) {
return _data.blob()
}).then(function (_blob) {
var task=firebase.storage().ref('images/12312355.jpg').put(_blob);
task.on('state_changed',
function progress(snapshot){
},
function error(err){
$ionicPopup.alert({
title: err
})
},
function complete(){
$ionicPopup.alert({
title: "Imagen guardada!"
})
}
);
})
}
})
Capturing image from camera will return the imageUrl. If you want to convert to blob type then using the below code in processImage function.
//Read the file entry from the file URL
resolveLocalFileSystemURL(imgUrl, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function () {
var imgBlob = new Blob([this.result], {
type: file.type
});
var imgFile = imgBlob;
};
reader.readAsArrayBuffer(file);
});
}, function () {
//on Error
});
You can also refer
http://ourcodeworld.com/articles/read/22/solve-native-path-of-android-content-if-resolvelocalfilesystemurl-doesn-t-work
I am try to collect data and images from local server (Acquia Dev Desktop) using this Angular Js code
controller
var app = angular.module('App', []);
app.controller('Ctrl', function($scope, $http) {
$scope.images = [];
$http({
method : "GET",
url : 'http://docroot.com.dd:8083/catalogue/11/images/json'
}).then(function mySucces(response) {
$scope.images = response.data;
}, function myError(response) {
$scope.images = response.statusText;
});
});
Json
[{"image":" <a href=\"http:\/\/docroot.com.dd:8083\/sites\/docroot.com.dd\/files\/catalogues\/2016-09\/images\/Pty%20Prs.compressedjpg_Page1.jpg\">Property Press.compressedjpg_Page1.jpg<\/a>"}]
// i got out put like this :
<a href=\"http:\/\/docroot.com.dd:8083\/sites\/docroot.com.dd\/files\/catalogues\/2016-09\/images\/Pty%20Prs.compressedjpg_Page1.jpg\">Property Press.compressedjpg_Page1.jpg<\/a>
i need to collect only image url instead of the whole link ,
Well, sending HTML elements in a JSON doesn't seem good to but, anyway if you cannot change it...
For my part, I would parse the html string with the built-in XML parser.
Here is the code taken from this answer
//XML parser
var parseXml;
if (typeof window.DOMParser != "undefined") {
parseXml = function(xmlStr) {
//should work with any recent browser
return ( new window.DOMParser()).parseFromString(xmlStr, "text/xml");
};
} else if (typeof window.ActiveXObject != "undefined" &&
new window.ActiveXObject("Microsoft.XMLDOM")) {
//This part is intended to very old browsers
parseXml = function(xmlStr) {
var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(xmlStr);
return xmlDoc;
};
} else {
throw new Error("No XML parser found");
}
//Your code
var jsonContent= [{"image":" <a href=\"http:\/\/docroot.com.dd:8083\/sites\/docroot.com.dd\/files\/catalogues\/2016-09\/images\/Pty%20Prs.compressedjpg_Page1.jpg\">Property Press.compressedjpg_Page1.jpg<\/a>"}];
var elem = jsonContent[0].image;
var link = parseXml(elem);
try {
document.getElementById("out").innerHTML = link.documentElement.getAttribute("href");
} catch (e) {
alert(e);
}
<span id="out" />
I have a set of data within a users profile which holds the UID of all the posts they have liked. I am using a data snapshot to show these images within the users profile, but I would like to load it lazy or use ionic infinite scroll to load more items as the user scrolls.
I tried by making two duplicate snap shots. First one intialises the feed upon the page loading, and then I wanted the second one to load by using ionic infinite scroller.
But it doesn't work.
Does anyone know of a better way to do this?
service.js
getWardrobeFeed: function(){
var defered = $q.defer();
var user = User.getLoggedInUser();
var wardrobeKeyRef = new Firebase(FIREBASE_URL + '/userProfile/' + user.uid + '/wardrobe');
wardrobeKeyRef.orderByKey().limitToLast(2).on('child_added', function (snap) {
var imageId = snap.key();
userImageRef.child(imageId).on('value', function (snap) {
$timeout(function () {
if (snap.val() === null) {
delete userWardrobeFeed[imageId];
} else {
userWardrobeFeed[imageId] = snap.val();
}
});
});
});
wardrobeKeyRef.orderByKey().limitToLast(2).on('child_removed', function (snap) {
var imageId = snap.key();
$timeout(function () {
delete userWardrobeFeed[imageId];
});
});
defered.resolve(userWardrobeFeed);
return defered.promise;
},
getWardrobeItems: function(){
var defered = $q.defer();
var user = User.getLoggedInUser();
var wardrobeKeyRef = new Firebase(FIREBASE_URL + '/userProfile/' + user.uid + '/wardrobe');
wardrobeKeyRef.orderByKey().limitToFirst(2).on('child_added', function (snap) {
var imageId = snap.key();
userImageRef.child(imageId).on('value', function (snap) {
$timeout(function () {
if (snap.val() === null) {
delete userWardrobe[imageId];
} else {
userWardrobe[imageId] = snap.val();
}
});
});
});
wardrobeKeyRef.orderByKey().on('child_removed', function (snap) {
var imageId = snap.key();
$timeout(function () {
delete userWardrobe[imageId];
});
});
defered.resolve(userWardrobe);
return defered.promise;
},
controller.js
$scope.userWardrobe = [];
Service.getWardrobeFeed().then(function(items){
$scope.userWardrobe = items;
});
$scope.loadMore = function() {
Service.getWardrobeItems().then(function(items){
$scope.userWardrobe = $scope.userWardrobe.concat(items);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
I have a controller which loads data via Restangular like so:
var oneTopic = Restangular.one('topics', topic.id);
oneTopic.get({}, {"Authorization" : localStorageService.get('***')}).then(function(topic) {
topic.getList('comments', {}, {"Authorization" : localStorageService.get('***')}).then(function(comments){
$scope.comments = comments;
//console.log($scope.comments);
});
});
And then a function which posts a new comment and one that deletes a comment.
$scope.delComment = function(comment_id, author_id){
var comment = Restangular.one('comments', comment_id);
comment.remove({author_id: author_id}, {"Authorization" : localStorageService.get('***')}).then(function(){
// need to perform refresh here
});
};
$scope.postComment = function(mood) {
$scope.commentData.mood = mood;
comments.post($scope.commentData, {}, {"Authorization" : localStorageService.get('***')}).then(function(response){
// need to perform refresh here
}, function(response){
$scope.error = response.data.message;
})
};
How would I refresh the comments scope without reloading the page? The data is being populated in the HTML with an
<div ng-repeat="comment in comments">
Modify the existing array referenced by $scope.comments and the data binding will take care of it.
For example:
$scope.delComment = function(comment_id, author_id) {
var comment = Restangular.one('comments', comment_id);
comment.remove({ author_id: author_id }, { "Authorization": localStorageService.get('***')
}).then(function() {
// Some remove-from-array implementation, for example:
var c = $scope.comments;
for(var i = 0, l = c.length; i < l; i++) {
if (c[i].comment_id === comment_id) {
c = c.splice(i, 1);
break;
}
}
});
};