Uploading files to directory in Jhipster - angularjs

I'm trying to build the back and front end parts of files uploader in an app built with jhipster 4.0.0, with angularjs.
How can I proceed ? Jhipster is actually giving acess for creating blob type columns with the entities builder , but isn't it a bad idea to store image in the database?
So, how can I build that file uploader ?

Another option you can consider if you don't want to save the file/image as a blob to the database is to create a separate file upload/retrieval service (ours was using MongoDB gridFs as we were dealing with large files) and only send the file id (or file path) of the successfully uploaded file when you save/update the entity.
You can use ng-file-upload to help manage this, note that below code is using angularJS version 1.
<form name="editForm" role="form" novalidate ng-submit="save(userUploadedFile)" show-validation>
<div class="form-group">
<div ng-show="entity.image == null">
<label class="control-label" for="field_file">Image</label>
<input type="file" ngf-select ng-model="userUploadedFile" name="file" id="field_file"
ngf-max-size="8MB" ng-disabled="disableFile" ngf-change="upload($files)" ngf-accept="'image/*'"/>
<button type="button" ng-click="removeUserUploadedFile()" ng-show="userUploadedFile">Remove</button>
</div>
<div ng-show="editForm.file.$invalid">
<p class="help-block" ng-show="editForm.file.$error.maxSize">Error! Image exceeds 8MB file limit</p>
</div>
<my-server-file file-id="entity.image" on-delete="onRemoveServerFile()"/>
</div>
<!-- include submit button etc -->
</form>
The my-server-file directive:
angular.module('myApp')
.directive('myServerFile', function(UrlService, FileService, $log) {
return {
restrict: 'E',
scope: {
fileId: "=fileId",
callbackOnDelete: "&onDelete"
},
template : "<div ng-if='fileId'>" +
"<a ng-if='fileId' ng-href='{{serverFilePath}}' target='_blank' download='{{fileName}}'>{{fileName}}</a>" +
"<button type='button' ng-click='deleteServerFile()' ng-show='fileId'>Remove</button>" +
"</div>",
controller: ['$scope',
function($scope) {
$scope.getFile = function(fileId) {
if(fileId){
$scope.serverFilePath = UrlService.getContextPath() + '/api/file/' + fileId;
FileService.getFileMetaData(fileId).then(function(file){
$scope.fileName = file.name;
});
}
}
$scope.deleteServerFile = function(){
FileService.deleteFile($scope.fileId).then(function() {
$scope.callbackOnDelete();
});
}
}
],
link: function(scope, iElement, iAttrs, ctrl) {
scope.$watch('fileId', function(value) {
scope.getFile(value);
})
}
}
})
Your controller will need to upload the file before it saves.
'use strict';
angular.module('myApp').controller('myAppController',
['$scope', '$stateParams', '$uibModalInstance', 'entity', 'UrlService', 'Upload', '$timeout', 'MyEntity'
function($scope, $stateParams, $uibModalInstance, entity, UrlService, Upload, $timeout, MyEntity) {
$scope.entity = entity;
$scope.load = function(id) {
MyEntity.get({id : id}, function(result) {
$scope.entity = result;
});
};
$scope.onRemoveServerFile = function() {
//Need to remove the file reference from the entity.
$scope.entity.image = null;
if($scope.entity.id){
MyEntity.update($scope.entity);
}
}
$scope.removeUserUploadedFile = function() {
$scope.userUploadedFile = null;
}
var uploadFile = function(file){
file.upload = Upload.upload({
url: UrlService.getContextPath() + '/api/file',
file: file
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
$scope.entity.image = file.result.fileId;
saveEntity();
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
var onSaveSuccess = function (result) {
$scope.isSaving = false;
$scope.$emit('myApp:entityUpdate', result);
$uibModalInstance.close(result);
};
var onSaveError = function (result) {
$scope.isSaving = false;
};
var saveEntity = function() {
$scope.isSaving = true;
if ($scope.entity.id != null) {
MyEntity.update($scope.entity, onSaveSuccess, onSaveError);
} else {
MyEntity.save($scope.entity, onSaveSuccess, onSaveError);
}
};
$scope.save = function (file) {
if(file != null){
uploadFile(file);
}
else {
saveEntity();
}
};
}]);
This does introduce some drawbacks though, when you delete the entity you will need to delete the file separately.
Create a simple FileSerivce to interact with the backend.
angular.module('myApp')
.factory('FileService', function ($http) {
return {
getFile: function(fileId) {
return $http.get('api/file/' + fileId).then(function (response) {
return response.data;
});
},
getFileMetaData: function(fileId) {
return $http.get('api/file/' + fileId + '/metaData').then(function (response) {
return response.data;
});
},
deleteFile: function(fileId) {
return $http.delete('api/file/' + fileId);
}
}
});
And finally your REST controller, here we are delegating to a custom wrapper for GridFs but you could just save it to the file system and return the full path as the id.
#RestController
#RequestMapping("/api/file")
public class FileController {
private final Logger log = LoggerFactory.getLogger(FileController.class);
#Inject
private GridFsService gridFsService;
#RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> upload(#RequestParam("file") MultipartFile file)
throws IOException {
GridFSFile storeFile = null;
if (!file.isEmpty()) {
storeFile = gridFsService.storeFile(file);
}
Map<String, String> map = new HashMap<>();
map.put("fileId", storeFile.getId().toString());
return map;
}
#RequestMapping(value="/{fileId}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<InputStreamResource> getFile(
#PathVariable String fileId) throws IOException {
return gridFsService.getFile(fileId).map(f -> new ResponseEntity<> (
new InputStreamResource(f.getInputStream()),
HeaderUtil.createFileContentLengthAndContentTypeHeaders(f.getLength(), f.getContentType()),
HttpStatus.OK
)).orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
#RequestMapping(value="/{fileId}/metaData",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Map<String, String>> getFileMetaData(
#PathVariable String fileId) throws IOException {
Optional<GridFSDBFile> optFile = gridFsService.getFile(fileId);
if(!optFile.isPresent()){
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
GridFSDBFile file = optFile.get();
Map<String, String> map = new HashMap<>();
map.put("name", file.getFilename());
map.put("contentType", file.getContentType());
map.put("size", String.valueOf(FileUtils.byteCountToDisplaySize(file.getLength())));
return ResponseEntity.ok()
.body(map);
}
#RequestMapping(value="/{fileId}", method = RequestMethod.DELETE)
public void deleteFile(
#PathVariable String fileId) throws IOException {
log.debug("REST request to delete File : {}", fileId);
gridFsService.deleteFile(fileId);
}
}

Related

No popup window with AngularJS and typeahead

I have a problem with the typeahead directive. I try to get datas from my datas from my service via $http.get.
In the console output I can see that my datas are coming from the service but I don't get the popup window of the results.
Here is my code:
Html Template:
<input type="text" class="form-control" placeholder="Kundensuche" ng-model="selectedCompany" typeahead="c for c in companies($viewValue)" typeahead-no-results="noResults" typeahead-min-length="3">
Service:
var _search = function (route, id) {
return $http.get(serviceBase + 'api/' + route + '/search/' + id);
};
serviceHelperFactory.search = _search;
Controller:
$scope.companies = function (val) {
var output = [];
var promise = serviceHelper.search('companies', val);
promise.then(function (result) {
result.data.forEach(function (company) {
output.push(company.companyName);
//output.push(company);
});
console.log(output);
}, function (error) {
adminInvoiceService.serviceErrorMessage(error);
});
return output;
}
Thanks!
Ok, I fixed it!
For all with the same problem here is my solution!
$scope.companies = function (val) {
return $http.get('http://localhost:5569/api/companies/search/'+val).then(function (res) {
var companies = [];
console.log(companies);
res.data.forEach(function (item) {
companies.push(item);
});
console.log(companies);
return companies;
});
};

AngularJs file downloading WebAPI

I need to download a file from server using Web API and angularJs. I am using below code for in API controller. When i hit the API through browser i can able to download the file. i don't have no idea, what to do with angualar
Web API
public HttpResponseMessage GetBrandByFilter(string filePath)
{
filePath = "C:\\Temp\\DTA 517280.pdf"; //Just hard coded for testing
var fileinfo = new FileInfo(filePath);
try
{
var excelData = File.ReadAllBytes(filePath);
var result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(excelData);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
FileName = fileinfo.Name
};
return result;
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.ExpectationFailed, ex);
}
}
Angular Controller
$scope.downloadFile = function () {
var result = downloadFile(service, "URL path");
result.then(function (res, status, headers) {
//****
// looking for this code on success
//****
},
function (err) {
debugger;
handleException($scope, err);
})
};
If you want, you can use a directive like this:
angular.module('app')
.directive('fileDownload', [function () {
return {
restrict: 'A',
replace: true,
scope: {},
template: '<button class="btn btn-default" data-ng-click="download()"><span class="glyphicon glyphicon-download"></span></button>',
controller: ['$scope', '$element', '$attrs', '$timeout', function ($scope, $element, $attrs, $timeout) {
$scope.progress = 0;
function prepare(url) {
console.log("Please wait, Your download starts in a few seconds.", $scope.progress);
fakeProgress();
}
function success(url) {
console.log("download complete");
}
function error(response, url) {
console.log("Couldn't process your download!");
}
function fakeProgress() {
$timeout(function () {
if ($scope.progress < 95) {
$scope.progress += (96 - $scope.progress) / 2;
fakeProgress();
}
}, 250);
}
$scope.download = function () {
$scope.progress = 0;
$.fileDownload($attrs.href, { prepareCallback: prepare, successCallback: success, failCallback: error });
}
}]
}
}]);
and use it like this:
<a href="/yourfiletodownload.pdf" file-download></a>

angular and prettyphoto url from blobstorage

Prettyphoto stopped working after I changed the href url to an angular tag: {{something.uri}}
Javascript:
jQuery(".prettyphoto").prettyPhoto({
theme: 'pp_default',
overlay_gallery: false,
social_tools: false,
deeplinking: false,
theme: 'dark_rounded'
});
$("a[rel^='prettyPhoto']").prettyPhoto();
HTML:
<div ng-show="model.fileList" ng-repeat="fileList in model.fileList">
<a ng-href="{{fileList.uri}}" class="prettyphoto">
<img ng-src="{{fileList.uri}}" class="img-thumbnail" width="100" alt="" />
</a>
</div>
Angular scope from blobstorage:
fileList: [
{
parentContainerName: documents
uri: https://xxxxxx.blob.core.windows.net/documents/20140702.jpg
filename: 20140702.jpg
fileLengthKilobytes: 293
}
]
app.factory('storageService',
["$http", "$resource", "$q",
function ($http, $resource, $q) {
//resource to get summaryRoles
var resourceStorageManager = $resource('/api/storageManager/:id', { id: '#id' });
return {
getFileList: function () {
var deferred = $q.defer();
resourceStorageManager.query(, function (data) {
deferred.resolve(data);
}, function (status) {
deferred.reject(status);
}
);
return deferred.promise;
}
};
}]);
app.controller('startController', ['$scope', '$http', '$timeout', '$upload', 'storageService', 'settings',
function startController($scope, $http, $timeout, $upload, storageService, settings, profileRepository, notificationFactory, $q) {
$http.defaults.headers.common = { 'RequestVerificationToken': $scope.__RequestVerificationToken };
$scope.model = {};
$scope.model.fileList = null;
$scope.model.roundProgressData = {
label: 0,
percentage: 0.0
};
$scope.$on("pic_profileone_main", function (event, profileExtInfo1) {
$scope.changeprofilepicmodel1 = angular.copy(profileExtInfo1);
refreshServerFileList();
});
$scope.$on("pic_profiletwo_main", function (event, profileExtInfo2) {
$scope.changeprofilepicmodel2 = angular.copy(profileExtInfo2);
refreshServerFileList2();
});
$scope.onFileSelect = function ($files, callernumber, foldername, blobtype) {
if (callernumber == 1) {
$scope.blobModel = angular.copy($scope.changeprofilepicmodel1);
$scope.blobModel.folderName = foldername;
$scope.blobModel.blobTypeCode = blobtype;
} else if (callernumber == 2) {
$scope.blobModel = angular.copy($scope.changeprofilepicmodel2);
$scope.blobModel.folderName = foldername;
$scope.blobModel.blobTypeCode = blobtype;
}
$scope.selectedFiles = [];
$scope.model.progress = 0;
// Assuming there's more than one file being uploaded (we only have one)
// cancel all the uploads
if ($scope.upload && $scope.upload.length > 0) {
for (var i = 0; i < $scope.upload.length; i++) {
if ($scope.upload[i] != null) {
$scope.upload[i].abort();
}
}
}
$scope.upload = [];
$scope.uploadResult = [];
$scope.selectedFiles = $files;
// Ok, we only want one file to be uploaded
// let's take the first one and that's all
var $file = $files[0];
// Only first element, single file upload
(function (index) {
$scope.upload[index] = $upload.upload({
url: settings.constants.uploadURL,
headers: { 'myHeaderKey': 'myHeaderVal' },
method: 'POST',
data: $scope.blobModel,
file: $file,
fileFormDataName: 'myFile'
}).then(function (response) {
var look = response;
$scope.model.progress = 100;
// you could here set the model progress to 100 (when we reach this point we now that the file has been stored in azure storage)
$scope.uploadResult.push(response.data);
$scope.$emit('ClearUploadPics');
refreshServerFileList();
}, null, function (evt) {
// Another option is to stop here upadting the progress when it reaches 90%
// and update to 100% once the file has been already stored in azure storage
$scope.model.progress = parseInt(100.0 * evt.loaded / evt.total);
$scope.model.roundProgressData.label = $scope.model.progress + "%";
$scope.model.roundProgressData.percentage = ($scope.model.progress / 100);
});
})(0);
};
function refreshServerFileList() {
storageService.getFileList().then(function (data) {
$scope.model.fileList = data;
}
);
}
function initialize() {
refreshServerFileList();
}
initialize();
$scope.$on("ClearProgressBar", function (event) {
$scope.selectedFiles = null;
});
}]);
I hope this is okay and more readable.

Angularjs dependency injection of an instantiable class

I am trying to learn a little about AngularJS. I have created websites in ASP.NET before so I decided to try to create an AngularJS site with MVC. I downloaded this excellent example:
https://github.com/jph00/AngularTutorial/tree/master/AngularTutorial
I created my own site based upon it but I have a problem with the dependency injection in the AngularJS code.
I created a class called Hotel
public class Hotel
{
public int HotelId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Notes { get; set; }
}
In the AngularJS code I have a file called Emp.js
var HotelApp = angular.module('HotelApp', ['ngResource']).
HotelApp.factory('Hotel', function ($resource) {
return $resource('/api/Hotel/:HotelId', { HotelId: '#HotelId' }, { update: { method: 'PUT' } });});
I also have HotelApp declared in the div tag of the page where I need it;
<div ng-app="HotelApp" data-ng-controller="hotelController" class="container">
However when I set breakpoints and jump to them, Hotel is always undefined. The only difference between the GitHub example and my project is that my project uses cshtml (the GitHub example is html).
I have not seen many examples online of dependency injection with AngularJS but those I have seen don't use instantiable classes (as my example has). Is there any example out there of AngularJS like this (dependency injection in an MVC project using a class)?
Edit:this is the Controller class;
{
public class HotelController : ApiController
{
private HotelsContext db = new HotelsContext();
// GET api/<controller>
[HttpGet]
public IEnumerable<Hotel> Get()
{
return db.Hotels.AsEnumerable();
}
// GET api/<controller>/5
public Hotel Get(int id)
{
Hotel hotel = db.Hotels.Find(id);
if (hotel == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return hotel;
}
// POST api/<controller>
public HttpResponseMessage Post(Hotel hotel)
{
if (ModelState.IsValid)
{
db.Hotels.Add(hotel);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, hotel);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = hotel.HotelId }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// PUT api/<controller>/5
public HttpResponseMessage PutHotel(int id, Hotel hotel)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (id != hotel.HotelId)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.Entry(hotel).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
// DELETE api/<controller>/5
public HttpResponseMessage Delete(int id)
{
Hotel hotel = db.Hotels.Find(id);
if (hotel == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.Hotels.Remove(hotel);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, hotel);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
The AngularJS controller is;
function hotelController($scope, $http) {
$scope.loading = true;
$scope.addMode = false;
//Used to display the data
$http.get('/api/Hotel/').success(function (data) {
$scope.hotels = data;
$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
$scope.toggleEdit = function ($scope, $location, $routeParams, Hotel) {
alert("Edit 1");
$scope.action = "Update";
alert("Edit 2");
id = $scope.HotelId;
alert("id is " + id);
// $scope.item = Todo.get({ id: id });
this.hotel.editMode = !this.hotel.editMode;
};
//Used to save a record after edit
$scope.save = function ($scope, $location, $routeParams, Hotel) {
alert("scope item");
alert("Hotel " + Hotel.id);
$scope.item = Hotel.get({ id: id });
alert("scope.item" );
Hotel.update({ id: id }, $scope.item, function () {
// $location.path('/');
alert("id is " + id);
});
};
//Used to add a new record
$scope.add = function () {
$scope.loading = true;
$http.post('/api/Hotel/', this.newhotel).success(function (data) {
alert("Added Successfully!!");
$scope.addMode = false;
$scope.hotels.push(data);
$scope.loading = false;
}).error(function (data) {
$scope.error = "An Error has occured while Adding Friend! " + data;
$scope.loading = false;
});
};
//Used to edit a record
$scope.deletefriend = function () {
$scope.loading = true;
var friendid = this.hotel.FriendId;
$http.delete('/api/Hotel/' + friendid).success(function (data) {
alert("Deleted Successfully!!");
$.each($scope.hotels, function (i) {
if ($scope.hotels[i].FriendId === friendid) {
$scope.hotels.splice(i, 1);
return false;
}
});
$scope.loading = false;
}).error(function (data) {
$scope.error = "An Error has occured while Saving Friend! " + data;
$scope.loading = false;
});
};
}
This has been resolved for me. The problem was the controller function had to be changed to get a reference to the Hotel class.
It was
function hotelController($scope, $http) {
but is now
function hotelController($scope, Hotel) {
If anybody needs further clarification contact me.
You need to define your controller and pass Hotel as a dependency.
DEMO
var HotelApp = angular.module('HotelApp', []);
HotelApp.factory('Hotel', [function() {
return {
run: function() {
alert("run");
}
}
}]);
HotelApp.controller("hotelController", ["$scope", "Hotel",
function($scope, Hotel) {
Hotel.run();
}
]);
Good read on dependency injection in angular.
EDIT:
Remove $scope, $location, $routeParams and Hotel parameters. You need to add those as dependency in your controller like in the example above.
$scope.toggleEdit = function($scope, $location, $routeParams, Hotel) {
alert("Edit 1");
$scope.action = "Update";
alert("Edit 2");
id = $scope.HotelId;
alert("id is " + id);
// $scope.item = Todo.get({ id: id });
this.hotel.editMode = !this.hotel.editMode;
};
//Used to save a record after edit
$scope.save = function($scope, $location, $routeParams, Hotel) {
alert("scope item");
alert("Hotel " + Hotel.id);
$scope.item = Hotel.get({ id: id });
alert("scope.item");
Hotel.update({ id: id }, $scope.item, function() {
// $location.path('/');
alert("id is " + id);
});
};

AngularJS Chart Directive - Data loaded in async service not updating chart

I am having one chart directive created, and I am bootstrpping the app after loading google api. In following code, a simple data table is working fine. But when I load data from server in async manner, chart is not being displayed.
Controller
'use strict';
myNetaInfoApp.controller('allCandidatesController', [
'$scope','allCandidates2009Svc', '$timeout',
function ($scope, allCandidates2009Svc, $timeout) {
$scope.data1 = {};
$scope.data1.dataTable = new google.visualization.DataTable();
$scope.data1.dataTable.addColumn("string", "Party");
$scope.data1.dataTable.addColumn("number", "qty");
$scope.data1.dataTable.title = "ASDF";
$timeout( function (oldval, newval) {
allCandidates2009Svc.GetPartyCriminalCount().then(function(netasParty) {
var i = 0;
for (var key in netasParty) {
$scope.data1.dataTable.addRow([key.toString(), netasParty[key]]);
i++;
if (i > 20) break;
}
});
});
$scope.dataAll = $scope.data1;
//sample data
$scope.data2 = {};
$scope.data2.dataTable = new google.visualization.DataTable();
$scope.data2.dataTable.addColumn("string", "Name");
$scope.data2.dataTable.addColumn("number", "Qty");
$scope.data2.dataTable.addRow(["Test", 1]);
$scope.data2.dataTable.addRow(["Test2", 2]);
$scope.data2.dataTable.addRow(["Test3", 3]);
}
]);
Service
'use strict';
myNetaInfoApp.factory('allCandidates2009Svc', ['$http', '$q',
function ($http, $q) {
var netas;
return {
GetPartyCriminalCount: function () {
var deferred = $q.defer();
$http.get('../../data/AllCandidates2009.json')
.then(function (res) {
netas = res;
if (netas) {
var finalObj = {};
_.each(netas.data, function(neta) {
finalObj[neta.pty] = finalObj[neta.pty] ? finalObj[neta.pty] + 1 : 1;
});
deferred.resolve(finalObj);
}
});
return deferred.promise;
}
};
}]);
Directive
"use strict";
var googleChart = googleChart || angular.module("googleChart", []);
googleChart.directive("googleChart", function () {
return {
restrict: "A",
link: function ($scope, $elem, $attr) {
var dt = $scope[$attr.ngModel].dataTable;
var options = {};
if ($scope[$attr.ngModel].title)
options.title = $scope[$attr.ngModel].title;
var googleChart = new google.visualization[$attr.googleChart]($elem[0]);
$scope.$watch($attr.ngModel, function (oldval, newval) {
googleChart.draw(dt, options);
});
}
};
});
HTML
<div ng-controller="allCandidatesController">
<div class="col-lg-6">
<h2>Parties and Candidates with Criminal Charges</h2>
<div google-chart="PieChart" ng-model="dataAll" class="bigGraph"></div>
<!--<p><a class="btn btn-primary" href="#" role="button">View details ยป</a></p>-->
</div>
<div class="col-lg-6">
<h2>Heading</h2>
<div google-chart="BarChart" ng-model="data2" class="bigGraph"></div>
</div>
</div>
I think you need to wrap your function body in allCandidates2009Svc factory with scope.$apply(). But the return deferred.resolve() will be outside scope.$apply().
function asyncGreet(name) {
var deferred = $q.defer();
setTimeout(function() {
// since this fn executes async in a future turn of the event loop, we need to wrap
// our code into an $apply call so that the model changes are properly observed.
scope.$apply(function() {
deferred.notify('About to greet ' + name + '.');
if (okToGreet(name)) {
deferred.resolve('Hello, ' + name + '!');
} else {
deferred.reject('Greeting ' + name + ' is not allowed.');
}
});
}, 1000);
return deferred.promise;
}
Read the docs here
http://docs.angularjs.org/api/ng.$q

Resources