Umbraco 7 custom property editor using angular file upload - javascript

I am using angular file upload in a custom property editor for Umbraco 7.0.3. I am following this tutorial in order to create the editor.
I am quite new to angular, so my question maybe trivial for some of you: I cannot resolve dependency to file upload service in my controller soon enough. My HTML template looks like:
<div ng-controller="MyCustomController">
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</div>
The controller function would need $upload service as an argument, however I inject that service at the beginning of the function:
angular.module("umbraco")
.controller("MyCustomController", function ($scope, assetService, $upload) {
assetsService
.load([
"/App_Plugins/MyCustomPlugin/angular-file-upload.min.js",
])
.then(function () {
alert('upload service loaded');
});
$scope.onFileSelect = function ($files) {
alert('file selected');
}
});
So, it is definitely not right this way. I was trying to load the upload service before the controller initialization, however it loads asynchronously, so the service cannot get defined before the controller anyway.
How can I declare my controller function only after the upload service is loaded, or how can I get a reference to the service other than an argument?
Thanks,
EDIT
The only solution I've found so far was to include the actual file upload codebase into the controller of the custom property editor. I used this paper as a starting point for my own codebase for its simplicity. However I am still looking for the 'proper' way of loading an external module in this case.

Include your code as a service instead.
The code angular.module line can take extra parameters if you see its documentation page. It is here that you should look to include any third party libs. For example, I use ngTable - an AngularJS wrapper around a jQuery sortable and filterable table plugin. To include its usage, I have to add it as a service to the current application's module like so:
var app = angular.module("umbraco", ['ngTable']);
All I then have to remember to do is to reference the scripts, and I can use the code as though I had included the body of the code itself. Therefore, I presume that you would reference your service JS files, and write your code to reference the service like this:
angular.module("umbraco", "MyCustomController");
I would however rename the code as services rather than controllers.
It's a steep learning curve for AngularJS, and even when you've used it a lot, there are a lot of common gotchas. I hope this explains it a bit more.

Related

Angular directive to load JS files for the other directives

I'm trying to minimize js/css/html footrpint for the user and to load only the files really needed. I've utilized RequireJS for that.
For my templates I'm trying to implement someting similar to
using section in C# or ///< reference path='...' > in TypeScript
But somehow depending on my template content it does or doesn't instantiate depends-on directive depending on template I have:
Works:
<depends-on path="..\..\test"></depends-on>
<login-form></login-form>
Doesn't work:
<depends-on path="..\..\test"></depends-on>
<login-form></login-form>
<other-directive></other-directive>
Doesn't work:
<div>
<depends-on path="..\..\test"></depends-on>
<login-form></login-form>
</div>
I'm obviously missing the way Angular parses and processes templates.
Is there a way to achieve what I'm trying to do?
OK, the problem was that it didn't wait until all directive template depends on are loaded. To ensure dependencies are loaded, dependent code should be in callback passed to require function.

Loading One Controller Per View AngularJS

I have an Spring + AngularJS Web Application with the following angular file structure.
mainmodule.js - where all config and routing's are
controller1.js
controller2.js
my main page is home.jsp where I imported all these files. As project goes bigger, I guess we have little over 50 files overall. So instead of dumping them in home.jsp, I would like to load them in it's corresponding view files. But when I tried to load controller1.js in corresponding JSP file, I get the below error.
[ng:areq] http://errors.angularjs.org/1.4.4/ng/areq?p0=dashboardController&p1=not%20aNaNunction%2C%20got%20undefined
Can someone help me identify what is the issue and how can I achieve this?
BTW I am using ui-router instead of default ngRoute.
One way of dealing with that scenario is to define a resolve property on each route and assign it a function that returns a promise. The function can handle dynamically loading the script containing the target controller and resolve the promise once the load is complete. For example:
$routeProvider
.when('/customers',
{
templateUrl: '/app/views/customers.html',
resolve: resolveController('/app/controllers/customersController.js')
});
But the best solution to your problem would be to use RequireJS framework with AngularJS for dynamically loading controllers per view.
There is very interesting source that explains about this : http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs
RequireJS official website: http://requirejs.org

updating angularjs libraries causes error in angular.bootstrap()

We have a legacy framework that we're looking to be able to do some major updates to soon. As part of this, we're working at bringing all our library files up to date. During this process, we upgraded angularjs from 1.0.7 to 1.3.13. Suddenly, we're getting a show-stopping error.
Error: [ng:areq] http://errors.angularjs.org/1.3.13/ng/areq?p0=MainCtrl&p1=not%20a%20function%2C%20got%20undefined
The question is: Why does this error happen when we upgrade to the newest library, and how am I supposed to do this now? I will add the most relevant lines of code below, and I can add more as requested, but it's kind of complex and I'm not sure how to break it down to something easy to stick into here.
The error occurs at angular.boostrap() The relevant code shows like so:
angular.module('app',['DataTools','ClientDataTools']);
angular.bootstrap(document, ['app']);
Main Ctrl is defined as such:
function MainCtrl($scope, $compile) {
The file structure is as such:
load.js
run.js
dataTools.js
load / controllers.js
load / config.js
load / ClientDataTools.js
load / libraries.html
The automatically generated html loads up along with the js code found in load.js. This first thing it does is load up libraries.html, which contains the imports for run.js, dataTools.js, controllers.js, and ClintDataTools.js. The code in load.js then calls a function defined in run.js. This function loads config.js and applies the settings there while going through and using jQuery to add angular tags to the form found in the automatically generated html. It then runs the angular.module() and angular.bootstrap() commands.
controllers.js holds the MainCtrl declaration. config.js is just a json string. dataTools.js and ClientDataTools.js holds the directives used by the angular - this error still happens even when removing the directive files, so I don't think they're part of it, but they are included here out of completeness of the issue..
And no, I can't just change the html in the form in the first place. I don't have access to it. It's automatically generated html to which we wish to add intelligent behavior like preventative data checking. It's an automatically generated form that we'd like to work a little more responsively. Please don't recommend just putting the angularjs markup into the html, and please don't ask why we can't touch the original html.
The way of declaring controller with
function MyCtrl() {}
has been deprecated - try declaring like
angular.module("app").controller("MyCtrl", function() {})

Angular js works on jsfiddle but not on my machine Strange ERROR

i am a beginner when it comes to angular
so here is the fiddle
http://jsfiddle.net/prantikv/knc6vrd9/1/
i have an simple app and as you can see i am just trying out the basics.
The example works fine on jsfiddle but when i run it on my machine i get a huge piece of error staring like this
Error: [ng:areq] Argument 'SimpleCont' is not a function, got undefined
And the ng-repeat doesnt show any output and the text input also doesnt work as well
i have run the page via a local wamp server as well and get the same result
Ommit creating a function, since angularjs is modular and provides you mechanism to create controllers, which can be used in applications.
So in your code, instead of:
function SimpleCont($scope){
$scope.nameList=[
{firstname:'john'},
{firstname:'jane'}
];
}
Create module and controller within it. First use module method from angular, which takes as first parameter name of module ( later to include in ng-app ) and as a second parameter dependency list, which in this situation is empty.
angular.module('myApp', []).
Then invoke controller function on module.
Module method always return itself, so you can add later another contorllers by using dot ..
controller('SimpleCont', function(){
this.nameList=[
{firstname:'john'},
{firstname:'jane'}
];
});
This is code instead of function, this code sets module and assign controller to it.
In your application to use module and created controller within it, set ng-app properly.
instead of:
<div ng-app>
use:
<div ng-app="myApp">
Generally good to know how to create controllers and modules in angularjs for beggining, because later you can learn other curious things like services, factories and also get to know what is $http service and how to use it for making ajax calls.
Also good to automate work thanks to grunt, karma and yeoman.
Here is good tutorial to start.
Here is about yeoman a tool you can use to work with angular.

Environment Setup egghead.io Tutorials?

hope things are going well.
I'm attempting to setup my development environment to be able to effectively follow the AngularJS tutorials on http://egghead.io/. I've followed the tutorial on http://docs.angularjs.org/tutorial and have since then been playing around with the angular-seed skeleton. I have successfully set up the angular-seed skeleton and am able to fully run it.
When I attempt to create js files with functions, such as the one in video 2. I'm not able to properly bind it to html element on index.html. I believe the issue may be with how routing is implemented in the angular-seed. I have node.js installed and am able to start the web server from the scripts folder in the angular-seed.
I'm really excited to begin working with AngularJS after I had the opportunity to work with ASP.NET MVC 4. I really like the information John provides in the tutorials on egghead.io, but I'm currently unable to fully emulate his instructions. It looks like he is JetBrains WebStorm, but I have no interest in purchasing it, if possible.
Any help would greatly be appreciated.
Thanks!
Edit 1:
For Example. In video 2 on the egghead.io tutorials. He creates a js file called main.js where he put a customer function and refers to it as an angular controller in index.html:
function FirstCtrl($scope){
$scope.data = {message: "Hello"};
}
Wouldn't a controller need something to exent of:
angualar.module('myApp',[]).controller('FirstCtrl', function(...){});
For angular to have it work as a controller on index.html? I'm able to add some of these functions to controllers.js of the angular-seed and make them work to some extent. Would it best to perhaps still use angular-seed and put the controllers/model/etc he displays some way into it's structure?
I ended up using angular-seed and placing the controllers/services/etc he is creating into controller.js for the first few videos. I was able to successfully output the correct information he is displaying in the videos. By the end of video 5, my code in controllers.js looked something like this:
'use strict';
/* Controllers */
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
return {message:"I'm data from a service"}
})
myApp.controller('FirstCtrl', function FirstCtrl($scope, Data){
$scope.data = Data;
});
myApp.controller('SecondCtrl', function SecondCtrl($scope, Data){
$scope.data = Data;
$scope.reversedMessage = function (message) {
return message.split("").reverse().join("");
}
});
At first I was using sublime text 2 and command line (node.js expressjs server), but recently I started using Visual Studio and created an empty website. I transferred all the folders/files of angular-seed into the website structure and I longer need to run node.js expressJS from the scripts\web-server.js. VS2013 has angularJS auto-complete features so it makes it easier.
I really like his tutorials and I'm glad I'm now able to successfully follow them to start learning angularJS.
Thanks!

Categories