1

I have a setup where I am using a service to send data to a proxy server. It looks like this:

    angular.module('app').service('apiService', ApiService);

function ApiService($http) {
    this.$http = $http;
};

ApiService.prototype.uploadFile = function(fileContent) {
    $.ajax({
        url: "/space_uploadFile/",
        type: "POST",
        dataType: "json",
        data: {
            fileContent: fileContent
        },

        contentType: "application/json",
        cache: false,
        timeout: 5000,
        complete: function() {
          //called when complete
          console.log('process complete');
        },
        success: function(data) {
          console.log(data);
          console.log('process success');
       },
        error: function() {
          console.log('process error');
        },
      });
};

next I am calling a directive that handles file loading and cropping of the image

use strict';
angular
    .module('app')
    /**
    * The ng-thumb directive
    * @author: nerv
    * @version: 0.1.2, 2014-01-09
    */
    .directive('ngThumb', ['$window', 'apiService', function($window, apiService) {
        var helper = {
            support: !!($window.FileReader && $window.CanvasRenderingContext2D),
            isFile: function(item) {
                return angular.isObject(item) && item instanceof $window.File;
            },
            isImage: function(file) {
                var type =  '|' + file.type.slice(file.type.lastIndexOf('/') + 1) + '|';
                return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
            }
        };

        return {
            restrict: 'A',
            template: '<canvas/>',
            link: function(scope, element, attributes) {
                if (!helper.support) return;

                var params = scope.$eval(attributes.ngThumb);

                if (!helper.isFile(params.file)) return;
                if (!helper.isImage(params.file)) return;

                var canvas = element.find('canvas');
                var reader = new FileReader();

                reader.onload = onLoadFile;
                reader.readAsDataURL(params.file);


                function onLoadFile(event) {
                    var img = new Image();
                    img.onload = onLoadImage;
                    img.src = event.target.result;
                }
                function uploadFile(imageData){
                    var self = this;
                    apiService.uploadFile(imageData);
                }

                function onLoadImage() {
                    var width, height;
                    if (params.height>params.width) {
                        width=params.width*3;
                        height=width;
                    } else {
                        height = params.height*3;
                        width=height;
                    }
                    var maxWidth=600;
                    if (width<maxWidth) {   
                        maxWidth=width;
                    }
                    //width = params.width || this.width / this.height * params.height;

                    canvas.attr({ width: width, height: height });
                    canvas[0].getContext('2d').drawImage(this, 0, 0, maxWidth, maxWidth, 0,0, width, height);
                    //canvas[0].getContext('2d').drawImage(this, 0, 0, width, height);
                    var image = canvas[0].toDataURL();
                    uploadFile(image);
                }
            }
        };
    }]);

now I would need the data returned by the Ajax request (data variable) to be passed to my controller

angular.module('app').controller('newProjectController', newProjectController);


function newProjectController($rootScope, $scope, $location, apiService, FileUploader) {
    this.apiService = apiService;
    /*$scope.encoded = $base64.encode('a string');
    console.log($scope.encoded);
    $scope.decoded = $base64.decode('YSBzdHJpbmc=');*/
    $rootScope.img="";

    var uploader = $scope.uploader = new FileUploader({
            url: '/space_uploadFile'
        });

        // FILTERS

        uploader.filters.push({
            name: 'imageFilter',
            fn: function(item /*{File|FileLikeObject}*/, options) {
                var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
                return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
            }
        });
} 

I cannot figure a way to either inject my $rootScope to the service or return data from the Ajax request to the directive. For other uploads I'm using $http.get(...) but I couldn't figure out how to do that using the json-encoded base64 image.

Can someone give me a hint? thanks already!

UPDATE 1. I've tried with Daniels suggestion. My watch looks like this

$scope.file=apiService.file;

        $scope.$watch("apiService.file", function (newVal, oldVal, scope) {
            console.log(newVal);
            console.log("update");
        });

The problem is it gets called onload but not when the variable is updated... What's wrong here?

2
  • Is the service , one-time-call or calls to the ApiService can be dynamic? If it is a one-time call then you can just resolve this call in your routeConfig before the controller is loaded. Commented Sep 2, 2016 at 13:38
  • the service is dynamically called Commented Sep 6, 2016 at 7:09

1 Answer 1

2

You can store the response in the service and then access it in the controller by injecting the service to it. You can put a watcher on the file variable to know when it has changed.

function ApiService($http) {
  this.$http = $http;
  this.file = {};
};

ApiService.prototype.uploadFile = function(fileContent) {
  $.ajax({
    //...
    success: function(data) {
      this.file = data;
    }
  //...
  });
};

Another option would be to send the responsedata to your controller using a $rootscope.$broadcast() event.

Sign up to request clarification or add additional context in comments.

6 Comments

can you explain or post an example of how to watch a variable? I am quite new to angular and up to now have only used basic functionality
looked at it and updated my code with what I thought would be the solution. Apparently it's not. Maybe you can help?
the problem I see with this is that my APIservice ajax request is actually inside the ApiService.prototype rather than directly at the APIservice level... So this still doesn't help
Why should that be a problem? The this context of the Service is still available in the prototype function!
I would also recommend using a factory instead of a service, I think it makes the context clearer and easier to read/understand since you can skip using this altogether.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.