2

This may look like a silly question, but it almost take an entire 3 hours, but still couldn't figure out what I have done wrong here. Possibly some one can point out the reason and how to fix this issue (I feel this is a easy fix, but still couldn't see it). So here's the matter, I have this javascript library integrated to angularJS application. I used a angular factory to provide this service to where it needs, so I can bind this to a single button click event, and initiate the functionalities of the integrated library. Now I need to take some values as parameters from the controller this factory function uses and pass those values from the factory to controller which is the controller that responsible for initiate the third party library. here's what I have so far.

This is a git repository with the same error

enter image description here

imageEditor factory

(function() {
    'use strict';

    angular.module('appEdit').factory('imageEditorService', [
        '$mdDialog',imageEditorService
    ]);

    function imageEditorService($mdDialog) {
        return {

            showImageEditorDialog: function (_width,_height) {

                return $mdDialog.show({
                    controller: 'imageEditorCtrl',
                    templateUrl: './imageEditor.html',
                    clickOutsideToClose: true,
                    locals: {
                        initialData: null,
                        width: _width,
                        height: _height
                    }
                });
            },
        };
    }
})();

imageEditor Controller

(function() {
    'use strict';
    angular.module("appEdit").controller("imageEditorCtrl" , ['width','height',imageEditorCtrl]);


    function imageEditorCtrl(width,height) {
        //this outputs the width, height passed to this properly
        console.log(width+','+height);

        setTimeout(
            () => {

                var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {
                    includeUI: {
                        loadImage: {
                            path: './images/imageEditor/test.png',
                            name: 'SampleImage'
                        },
                        theme: blackTheme,
                        initMenu: 'crop',
                        menuBarPosition: 'bottom'
                    },
                    cssMaxWidth: 700,
                    cssMaxHeight: 300
                });

                // this is where I need the width, height should be bound
                imageEditor.setCropRect(width,height);

                window.onresize = function () {
                    imageEditor.ui.resizeEditor();
                }

            }
            , 1000)
    };

})();

mainController

(function(){
"use strict";

angular.module('appEdit')
    .controller('mainCtrl', ['$scope','imageEditorService', function ($scope, imageEditorService) {

        $scope.openImageEditorDialog = function (width, height) {
            imageEditorService.showImageEditorDialog(width, height);
    };
    }]);
 })();

HTML where I used this mainCtrl

<div ng-controller="mainCtrl">
    <md-button ng-click="openImageEditorDialog(400,200)">Open</md-button>
</div>

The Error

angular.js:14110 Error: [$injector:unpr] Unknown provider: widthProvider <- width <- imageEditorCtrl http://errors.angularjs.org/1.5.9/$injector/unpr?p0=widthProvider%20%3C-%20width%20%3C-%20imageEditorCtrl at http://localhost:1337/vendor/angular/angular.js:68:12 at http://localhost:1337/vendor/angular/angular.js:4554:19 at Object.getService [as get] (http://localhost:1337/vendor/angular/angular.js:4707:32) at http://localhost:1337/vendor/angular/angular.js:4559:45 at getService (http://localhost:1337/vendor/angular/angular.js:4707:32) at injectionArgs (http://localhost:1337/vendor/angular/angular.js:4732:58) at Object.invoke (http://localhost:1337/vendor/angular/angular.js:4754:18) at $controllerInit (http://localhost:1337/vendor/angular/angular.js:10518:34) at nodeLinkFn (http://localhost:1337/vendor/angular/angular.js:9416:34) at compositeLinkFn (http://localhost:1337/vendor/angular/angular.js:8757:13) undefined

I know this error occurs with a typo kind of issues, but here I can not understand why this occurs. with console.log(width+','+height) I could confirm the width and height is set properly and it comes to the controller, but the problem is with the provided error, entire functionality of the third party library is breaks down(it won't initiate at all). without the width, height parameters it works just fine

12
  • Where should these values come from? From the URL? From inputs in the view? Commented Oct 8, 2018 at 11:49
  • @RenatoLucasChitolina I just updated the question, for better understand. Hop you can understand the problem than before now. Commented Oct 8, 2018 at 11:53
  • Which version of angularJS you are using? Commented Oct 8, 2018 at 12:09
  • Where are you getting width and height for this line imageEditor.setCropRect(width,height); Commented Oct 8, 2018 at 12:10
  • @GangadharJannu it's angular v-1.7.5 and function imageEditorCtrl(width,height) this is where it comes. Commented Oct 8, 2018 at 12:15

3 Answers 3

1

Seems like the issue is with Dependency Injection.

Change your imageEditor Controller definition as below

(function () {
    'use strict';
    angular.module("appEdit").controller("imageEditorCtrl", [imageEditorCtrl]);

    function imageEditorCtrl($scope, $mdDialog, initialData, width, height) {
        this.$onInit = function () {
            var imageEditor = new tui.ImageEditor('#tui-image-editor-container', {
                includeUI: {
                    loadImage: {
                        path: './images/imageEditor/test.png',
                        name: 'SampleImage'
                    },
                    theme: blackTheme,
                    initMenu: 'crop',
                    menuBarPosition: 'bottom'
                },
                cssMaxWidth: 700,
                cssMaxHeight: 300
            });

            // this is where I need the width, height should be bound
            imageEditor.setCropRect(width, height);

            window.onresize = function () {
                imageEditor.ui.resizeEditor();
            }
        }
    };
})();
Sign up to request clarification or add additional context in comments.

12 Comments

Already try those bro, still no luck. no errors with $scope or $mdDialog, it's just the width and height gives the error. I'll try to add a plunker or fiddle regarding this.
That would really help us in debug the issue
I have linked a git repo with the same error, You can refer to that.
still not working?. Have you tried my updated answer?
I tried the updated one mate, still no luck. width and height undefined then. I suspect it happens with setTimeout
|
0

There are several problems with your code, but the main thing you need to get down is Dependency Injection(DI) in angularJS:

https://docs.angularjs.org/guide/di

You created your service, imageEditorService, but you need to inject it in your controller:

angular.module("appEdit").controller("imageEditorCtrl" , ['imageEditorService',imageEditorCtrl]);


function imageEditorCtrl(imageEditorService) {

You cannot inject 'height' and 'width' into your controller, as they are not 'providers', as your error suggests. To use the service in your controller, call:

imageEditorService.showImageEditorDialog(height, width); // Specify the height and width. 

That said, I am not sure what you want to do in your controller. Do you want to instantiate a new tui.ImageEditor, or do you want to use your imageEditorService?

If you want to use tui.ImageEditor, use your factory/service to do that.

Some tips: Make sure you understand the difference between controllers and services/factories/providers. Also, get familiar with the controller lifecycle, such as the build-in init hook:

What is the lifecycle of an AngularJS Controller?.

1 Comment

Seems like you didn't understand the question properly. I used this factory to just initiate the image editor. so it makes it ease to inject into any controller and using it I can instantiate the image editor where ever I need. BTW I know the difference between a controller/service/factory and a provider. This way I can pass the values to the controller, which is the controller bound to the factory, but when I use this method to pass the values, the image editor instantiation disrupted some how. How ever I can see the question doesn't seems clear, I'll update the question.
0

Finally I sort it out, I did a really really stupid thing, and as I was suspecting It was just an easy fix. I just bind the controller again to the templateHTML, and that causes the problem. it's just confuse the build flow with the same controller which binds to a HTML Element twice. So just removing the controller bind from the templateHTML file, just fix the problem.

previous templateURL file

<div ng-controller="imageEditorCtrl"> <!--this line which causes the problem with controller bind-->
    <div style="width:80vw; height: 500px">
        <div id="tui-image-editor-container"></div>
    </div>
</div>

fixed version

<div>
    <div style="width:80vw; height: 500px">
        <div id="tui-image-editor-container"></div>
    </div>
</div>

Comments

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.