Showing posts with label AngularJS. Show all posts
Showing posts with label AngularJS. Show all posts

Tuesday, December 19, 2017

How to Inject and Use AngularJS Services in Angular

Angular developers looking to upgrade their codebase from AngularJS to Angular (v2+) will probably use a hybrid approach via the UpgradeModule and migrate their code over time. During this process you'll probably need to inject and re-use one of your existing AngularJS services in an Angular component or provider. You may also need an existing built in AngularJS service (i.e. $routeParams, $location, etc.). This isn't difficult to do, and the steps are below.

1. Upgrade the AngularJS service/provider to Angular

In your Angular app module, use an Angular factory provider that will request the service from the AngularJS $injector.

providers: [
  { provide: 'myAngularJsService', useFactory: ($injector: any) => $injector.get('myAngularJsService'), deps: ['$injector'] },
  { provide: '$routeParams', useFactory: ($injector: any) => $injector.get('$routeParams'), deps: ['$injector'] }
]

2. Inject the upgraded service in Angular

Using @Inject you will be able to inject your upgraded service for use in an Angular component or provider.

export class MyAngularComponent{

constructor(
  @Inject('myAngularJsService') private myAngularJsService,
  @Inject('$routeParams') private $routeParams
)

  //Implementation...
  myAngularJsService.doSomething();
}

3. Optionally create your own service factory

It's advisable to create a separate factory so it is easier to reference and then upon full migration of code easily delete as well. One note that can be the Achilles heel of this method - it requires the ability to be able to ES6 style import your external module. If your legacy AngularJS code is sill using internal modules and not external modules, this will not be possible as using an old style internal module reference in Angular will not work. So if your entire app is already using external modules you can set up your own factory as shown below.

import { MyAngularJsService} from './my-angularJs.service';

export function myAngularJsServiceFactory(i: any) {
  return i.get('myAngularJsService');
}

export const myAngularJsServiceProvider = {
  provide: MyAngularJsService,
  useFactory: myAngularJsServiceFactory,
  deps: ['$injector']
};

Now it can be registered in the app module via the exported provider created above.

import { myAngularJsServiceProvider } from './upgraded-providers';

//app module or module implementation...
providers: [myAngularJsServiceProvider]

In the Angular component or provider where injected, you can just import the service and use directly in the constructor.

import { MyAngularJsService} from './my-angularJs.service';

export class MyAngularComponent{

constructor(
  private myAngularJsService: MyAngularJsService
)

  //Implementation...
  myAngularJsService.doSomething();
}

The advantage of the above method is now upon injecting, you don't have to use the string handle and will get proper type checking.

Wednesday, June 8, 2016

Is ASP.NET MVC the new WebForms because of Smart Client JS Web Apps?

In the last few years JavaScript, JavaScript frameworks, and the browser have matured exponentially providing us with AngularJS, React, Aurelia, Ember, and others. These frameworks allow for web developers to create performant and rich smart client JavaScript web applications (a.k.a SPAs). So what about ASP.NET and that old trustworthy MVC implementation? As an analogy, is MVC the new 'WebForms' as to how WebForms were viewed when MVC came to the scene? Is ASP.NET MVC obsolete or considered now 'old hat' from an implementation perspective? I think it is mostly 'yes' and just a bit of 'no' to that question and I'll provide points to both.



The bold answer is yes - MVC is a relic of days past and anyone that uses it has their head in the sand. Well maybe not quite and certainly not near being obsolete. However there is some merit to the fact that ASP.NET MVC is showing it's age as an implementation choice. There are many things that JS web applications do very well and architecturally speaking just make sense. 

To begin, the JS Frameworks by nature move the heavy rendering and presentation logic to the client. This removes the burden on the server of packaging both markup and data to send to the client. The server's main responsibility is now returning only data typically in the way of JSON payloads via RESTful services (i.e. NodeJS, WebAPI), as well as the web artifacts on an as needed basis (i.e. views, images, JS, etc.). With most frameworks, once the views and associated JS is brought to the client it is cached. The combination of client side processing + caching of data and website artifacts = highly performant web applications.

The 1st time most developers get accustomed to a JS Framework creating a web application, and experience how the line between desktop applications and web application almost is non-existent they often see the many benefits and don't look back.


Add atop of all this, most JS Frameworks were built with testing in mind, have massive adoption, huge amounts of support, examples, and training which adds up to something one can feel confident moving forward with as an implementation choice.

Another advantage of smart client JS Web Applications is the fact that they make sense architecturally. MVC by nature is and should be a presentation layer architecture. In ASP.NET MVC, I still see often the architecture abused and used as the full-blown implementation for Enterprise Applications. I don't blame most for doing this as the majority of  '101' examples show this implementation so it must be what is used for everything, right? Wrong. It's analogous for those of you that have used Angular 1.x and having the controller make $http calls directly, or abusing $scope as the do-all for the app. 

A tattle-tale sign of using MVC incorrectly is if the 'Model' is directly making database calls (i.e. EF or whatever) and then having the Controller make calls to methods on the Model. This then results in bloating either the model or controller (or both) with additional business logic or model hydration/shaping. MVC should be the top layer of the cake and only concerned with presentation layer logic and manipulation. JS Frameworks for the most part solve this problem naturally because of the separation now between the client and server. It's more difficult and many times not even possible to abuse the JS Web App client implementation that was done so often in ASP.NET MVC. Now one is forced to call the server for data, and then on the server another layered implementation can exist within the RESTful service to handle logic, rules, additional underlying calls, hydration/shaping, etc.. With a JS Web App we should relegate the MV* implementation client side to only presentation layer concerns, and allow the server to do what it does best and offer up reusable RESTful endpoints, encapsulating all server logic. With MVC this was absolutely possible, however it was typically a conscious decision and had to be made usually at the project's onset in order to have decent SoC and testability. Otherwise the result would be behemoth of a web application stuffed into the slim MVC implementation. 

From a JavaScript perspective my experience as a whole in MVC usually yielded to a jQuery implementation for DOM manipulation and a multi-thousand line file named MyApp.js. At 1st this file seems like a good idea, but then it snowballs into a intermingled mess of reactionary code responding to events, registering callbacks, making AJAX calls, manipulating views, and a hundred other things all interwoven together. Most of the time I saw no forethought put into proper segregation using known JS patterns like the module or revealing module pattern, and mostly a mess of public values and methods that were a ticking time bomb of heavy maintenance. In JS Framework implementations, there is a separation of concerns between the Model and View logic allowing testing and scaling your application more correctly. The alleviates the need for JS DOM manipulation libraries like jQuery all together.

Let's pile on another thing helping out JS Web apps in the way of languages like TypeScript.
This gem which was originally created at Microsoft by the same guy that created C# and is OSS, is a superset of JavaScript and adds on a slew of features to help developers wrangle some of the JavaScript nuances. There isn't anyone here claiming JavaScript is a perfect language, but I'll tell you from 1st hand experience using TypeScript makes creating JS Web apps in my experience a whole lot easier. Static typing, build time checking of code, Interfaces and other language features that don't exist in JS, staying ahead of the ECMAScript standards and releases, OO familiarity, and many other goodies help make TypeScript a real joy to have in the toolbox when creating JS Web Apps.


So now let's look at the flip side of the coin: ASP.NET MVC's advantages. Well to begin Microsoft is doing ASP.NET in general a whole world of good in the way of .NET Core 1.0. From a project's physical structure and implantation, the new world of the web in VS.NET is brought inline with where the rest of the web and OSS community has already been in the last several years. This is to the tune of task runners like Gulp or Grunt, additional package managers in the way of NPM and Bower, .json configuration for many different project components or languages like TypeScript, and several other new changes. 

The irony is from WebForms to MVC we moved from a 'Convention over Configuration' phase. Now we are shifting back to 'Configuration over Convention'. However this is in a very good way. Instead of getting many tools, resources, and processes being dictated and packaged up by default, you need to tell your web app exactly what you want and how you want it to behave from start to finish. This is a good thing. We as developers should have full control over our applications and dictate this configuration. At first this might cause some heartburn as change sometimes does, but it's the right move and I applaud Microsoft. For so long I used to promote how much I liked living inside the comfortable confines of ASP.NET and VS.NET. This magic thing like 'bundling and minification' was done for me along with many other tasks to get up and running. There is a little more work now as this doesn't even exist anymore in .NET Core 1.0, but I can control and configure my apps to be lean and behave as I want them to.


So wait, what about the good bits of MVC?? The above was like a back-handed compliment about MVC finally catching up to more standard methods of configuring web applications. However there are a couple of big things MVC still has going for it.

1st it's quite mature. ASP.NET has been around since 2001 and the MVC implementation since 07`. That's almost 10 years going strong. In addition Microsoft is behind it and is now OSS. It's not going anywhere, anytime soon. If your looking for that rock of stability and being conservative MVC is a good choice. Keep in mind though, ASP.NET WebForms is stable and around too, but that doesn't mean it's the best decision.

2nd, because of it's maturity there are a slew of developers that have experience with using it and developing application for it. There are just some realities that exist. Things like deadlines and financial constraints are legitimate concerns. As the lead, architect, decision maker, etc. on your team you might have 10 developers that are strong in MVC and have relatively no experience with a JS Framework and JavaScript in general with a deadline fast approaching. Do you bite the bullet and try your hand at creating a JS Web App, or go with old trusty and bang it out in MVC? That's a decision you'll need to make and one I've encountered as well.

To sum things up, I do believe JS Web Apps are here and probably the best decision for net new web apps today. I personally view MVC as a bit of a heavy weight in the web ring and sometimes we need something a bit more lean to fight our development battle. I agree for the most part MVC is beginning to be viewed as the new 'WebForms' as far as making an analogy to how WebForms were viewed when MVC came to the scene. However as I've broken it down, ASP.NET MVC isn't going anywhere and is still a fine choice to make in certain scenarios. 

Who knows, maybe I'll be writing this same article in 5 years with the following title:

"Are JS Web Apps the new MVC because of WebAssembly?"

Thursday, November 12, 2015

Is Aurelia going to a realistic competitor?

The quick and legitimate answer to the title of this post is, "I don't know." However I wanted to do a little digging to see the potential for this relative newbie to the JS Framework arena that is already so competitive and overflowing. Just see this: 100+ JavaScript Frameworks For Web Developers

To provide some context, here is a visual from Google trends based on some of the major competing frameworks (note: no matter which combination of 'aurelia' I used the results were all the same). Even if this metric isn't perfect, it still provides some level of comparison for popularity:



This GitHub thread has some interesting comments from Rob Eisenberg over this past year on Aurelia. With all the talk of it being a competitor to JavaScript frameworks like React and Angular, I was curious about its backing and support. With those frameworks you have Facebook and Google respectively behind them. I was curious if Aurelia was just a bunch of devs revolting with a new framework out of angst for what happened with the lack of use for Durandal and the ill advised direction Angular 2.0 was going according to Rob, or in the long run would this be a serious contender.

It's no secret JS frameworks and libraries seem to come and go as do the seasons, and investing heavily in one is an important decision. Durandal seemed to have lost a flame quickly in this JS framework battle, so I'm curious how Aurelia will fare.

Here are some quotes from that link from Rob:
"From a business perspective, Aurelia is backed by Durandal, Inc. Durandal is a company that is dedicated to providing open, free and commercial tools/services for developers and businesses that create software using web technologies."
As a private company it is tough to see the backing or possible angel investors involved with Durandal. However for OSS with a passionate community this could be a moot point.

He does go on to mention:
"Durandal is positioned to begin raising Series A venture capital this month. That isn't to support the open source Aurelia project. That project does not need funding. Rather, it is to support Durandal Inc. which intends to offer a much richer set of tooling and services for those who want to leverage Aurelia and the web. We are building out a serious business and our entire platform will be built with Aurelia and for Aurelia. Our potential investors are very excited about our plans and we expect to have some cool stuff to show in the future"
So that could add some potential to Durandal Inc. to keep this thing moving forward. He continues on about the horsepower behind it's actual creation and continued development:
"Aurelia itself is solid due to the fact that it currently has a 12 person development team distributed throughout the world and a large active community, especially considering it was only announced a couple of months ago"
...a bit later he quotes:
"We have 17 members on our core team currently which contribute daily"
Well hopefully those 12-17 people remain passionate :D

I think the conservative decision today is to go with ReactJS or AngularJS with Aurelia being the bold one. I'm not thinking it's going to fade away anytime soon, but with so many competing frameworks it's important for it to catch some mainstream traction or the OSS community might loose steam working for a lost cause.

I for one hope it does succeed and becomes a bit more mainstream. When comparing the syntax for ReactJS, Angular 2.0, and Aurelia, I believe I'd choose Aurelia. Unfortunately for me I'm one in the camp that actually likes Angular 1.x and it's implementation so I don't really have any gripes to it currently for switching to something different. However its shortcomings in performance and implementation are certainly going to be addressed by the radically different 2.0 which still needs to grow on me a bit.

Time will tell and the community not I will answer this question by adoption (or lack thereof) of this framework and others in the upcoming months and years.

Wednesday, November 12, 2014

Upgrading to Angular 1.3: Global Controllers Not Supported by Default

If you recently upgraded to Angular 1.3.x, you my get the following JavaScript error when trying to run your application:

Error: [ng:areq] Argument 'MyController' is not a function, got undefined

This issue is a result of some breaking changes where AngularJS no longer supports global controllers set on the window object as of version 1.3. In reality if you have a production application using global controllers, it is not advised and would be a prime target of refactoring regardless. However you might of had a small test app or the like that upon upgrading Angular to v1.3.x it stops working unexpectedly. The intention behind this change was to prevent poor coding practices.

The actual breaking change is highlighted on GitHub here: https://github.com/angular/angular.js/blob/g3_v1_3/CHANGELOG.md#breaking-changes-13

I like how the use of global controllers according to the change was for, "examples, demos, and toy apps." I agree with the statements, so I'm OK with this change. It really is code smell to use controller functions in the global scope.

Let's look at code that would have worked in Angular versions prior with a trivial sample:

<body ng-app>
    <div ng-controller="MyController">
        <input ng-model='dataEntered' type='text' />
        <div>You entered: {{dataEntered}}</div>
    </div>
    <script src='/Scripts/angular.js'></script>
    <script type='text/javascript'>
        function MyController($scope) {
            $scope.dataEntered = null;
        };
    </script>
</body>

The breaking change requires one to register the Controller with a Module to provide scope and pull it off the global window object. The changes required are shown below:

<body ng-app="SimpleAngularApp">
    <div ng-controller="MyController">
        <input ng-model='dataEntered' type='text' />
        <div>You entered: {{dataEntered}}</div>
    </div>
    <script src='/Scripts/angular.js'></script>
    <script type='text/javascript'>
        (function () {
            function MyController($scope) {
                $scope.dataEntered = null;
            };
            angular.module("SimpleAngularApp", []).controller("MyController", ["$scope", MyController]);
        })();
    </script>
</body>

You might find this will have the biggest impact going forward when you are throwing together quick demos or examples using Plunker or a small test harness. Just remember to register the controller with a Module to prevent running into this error. 

There technically is a workaround if you must make a fix quickly, but not advised long term. You can choose to set $controllerProvider.allowGlobals(); which will allow the old code to run. You can read about it here: https://docs.angularjs.org/api/ng/provider/$controllerProvider

If your apps have previously been constructed using best practices, this should not impact you at all. For additional changes between Angular 1.2 and 1.3, see the following link: https://docs.angularjs.org/guide/migration