Web API Pros and Cons

With the new changes to the Web API, there has been a lot of discussion of where the new Web API technology fits in the ASP.NET Web stack. There are a lot of choices to build HTTP based applications available now on the stack – we’ve come a long way from when WebForms and Http Handlers/Modules where the only real options. Today we have WebForms, MVC, ASP.NET Web Pages, ASP.NET AJAX, WCF REST and now Web API as well as the core ASP.NET runtime to choose to build HTTP content with.

Web API definitely squarely addresses the ‘API’ aspect – building consumable services – rather than HTML content, but even to that end there are a lot of choices you have today. So where does Web API fit, and when doesn’t it?

 

What is a Web API?

HTTP ‘APIs’ are becoming increasingly more important with the rise of the many devices in use today. Most mobile devices like phones and tablets run Apps that are using data retrieved from the Web over HTTP. Desktop applications are also moving in this direction with more and more online content and syncing moving into even traditional desktop applications. The pending Windows 8 release promises an app like platform for both the desktop and other devices, that also emphasizes consuming data from the Cloud.

Likewise many Web browser hosted applications these days are relying on rich client functionality to create and manipulate the browser user interface, using AJAX rather than server generated HTML data to load up the user interface with data.

These mobile or rich Web applications use their HTTP connection to return data rather than HTML markup in the form of JSON or XML typically. But an API can also serve other kinds of data, like images or other binary files, or even text data and HTML (although that’s less common). A Web API is what feeds rich applications with data.

ASP.NET Web API aims to service this particular segment of Web development by providing easy semantics to route and handle incoming requests and an easy to use platform to serve HTTP data in just about any content format you choose to create and serve from the server.

 The .NET stack already includes a number of technologies that provide the ability to create HTTP service back ends, and it has done so since the very beginnings of the .NET platform. From raw HTTP Handlers and Modules in the core ASP.NET runtime, to high level platforms like ASP.NET MVC, Web Forms, ASP.NET AJAX and the WCF REST engine (which technically is not ASP.NET, but can integrate with it), you’ve always been able to handle just about any kind of HTTP request and response with ASP.NET. The beauty of the raw ASP.NET platform is that it provides you everything you need to build just about any type of HTTP application you can dream up from low level APIs/custom engines to high level HTML generation engine. ASP.NET as a core platform clearly has stood the test of time 10+ years later and all other frameworks like Web API are built on top of this ASP.NET core.

However, although it’s possible to create Web APIs / Services using any of the existing out of box .NET technologies, none of them have been a really nice fit for building arbitrary HTTP based APIs. Sure, you can use an HttpHandler to create just about anything, but you have to build a lot of plumbing to build something more complex like a comprehensive API that serves a variety of requests, handles multiple output formats and can easily pass data up to the server in a variety of ways. Likewise you can use ASP.NET MVC to handle routing and creating content in various formats fairly easily, but it doesn’t provide a great way to automatically negotiate content types and serve various content formats directly (it’s possible to do with some plumbing code of your own but not built in). Prior to Web API, Microsoft’s main push for HTTP services has been WCF REST, which was always an awkward technology that had a severe personality conflict, not being clear on whether it wanted to be part of WCF or purely a separate technology. In the end it didn’t do either WCF compatibility or WCF agnostic pure HTTP operation very well, which made for a very developer-unfriendly environment.

ASP.NET Web API differentiates itself from the previous Microsoft in-box HTTP service solutions in that it was built from the ground up around the HTTP protocol and its messaging semantics. Unlike WCF REST or ASP.NET AJAX with ASMX, it’s a brand new platform rather than bolted on technology that is supposed to work in the context of an existing framework. The strength of the new ASP.NET Web API is that it combines the best features of the platforms that came before it, to provide a comprehensive and very usable HTTP platform. Because it’s based on ASP.NET and borrows a lot of concepts from ASP.NET MVC, Web API should be immediately familiar and comfortable to most ASP.NET developers.

Here are some of the features that Web API provides:

  • Strong Support for URL Routing to produce clean URLs using familiar MVC style routing semantics
  • Content Negotiation based on Accept headers for request and response serialization
  • Support for a host of supported output formats including JSON, XML, ATOM
  • Strong default support for REST semantics but they are optional
  • Easily extensible Formatter support to add new input/output types
  • Deep support for more advanced HTTP features via HttpResponseMessage and HttpRequestMessage
    classes and strongly typed Enums to describe many HTTP operations
  • Convention based design that drives you into doing the right thing for HTTP Services
  • Very extensible, based on MVC like extensibility model of Formatters and Filters
  • Self-hostable in non-Web applications 
  • Testable using testing concepts similar to MVC

Web API is meant to handle any kind of HTTP input and produce output and status codes using the full spectrum of HTTP functionality available in a straight forward and flexible manner.

Looking at the list above you can see that a lot of functionality is very similar to ASP.NET MVC, so many ASP.NET developers should feel quite comfortable with the concepts of Web API. The Routing and core infrastructure of Web API are very similar to how MVC works providing many of the benefits of MVC, but with focus on HTTP access and manipulation in Controller methods rather than HTML generation in MVC.

There’s much improved support for content negotiation based on HTTP Accept headers with the framework capable of detecting automatically what content the client is sending and requesting and serving the appropriate data format in return. This seems like such a little and obvious thing, but it’s really important. Today’s service backends often are used by multiple clients/applications and being able to choose the right data format for what fits best for the client is very important.

While previous solutions were able to accomplish this using a variety of mixed features of WCF and ASP.NET, Web API combines all this functionality into a single robust server side HTTP framework that intrinsically understands the HTTP semantics and subtly drives you in the right direction for most operations. And when you need to customize or do something that is not built in, there are lots of hooks and overrides for most behaviors, and even many low level hook points that allow you to plug in custom functionality with relatively little effort.

If your primary focus of an application or even a part of an application is some sort of API then Web API makes great sense.

HTTP Services
If you’re building a comprehensive HTTP API that is to be consumed over the Web, Web API is a perfect fit. You can isolate the logic in Web API and build your application as a service breaking out the logic into controllers as needed. Because the primary interface is the service there’s no confusion of what should go where (MVC or API). Perfect fit.

Primary AJAX Backends
If you’re building rich client Web applications that are relying heavily on AJAX callbacks to serve its data, Web API is also a slam dunk. Again because much if not most of the business logic will probably end up in your Web API service logic, there’s no confusion over where logic should go and there’s no duplication. In Single Page Applications (SPA), typically there’s very little HTML based logic served other than bringing up a shell UI and then filling the data from the server with AJAX which means the business logic required for data retrieval and data acceptance and validation too lives in the Web API. Perfect fit.

Generic HTTP Endpoints
Another good fit are generic HTTP endpoints that to serve data or handle ‘utility’ type functionality in typical Web applications. If you need to implement an image server, or an upload handler in the past I’d implement that as an HTTP handler. With Web API you now have a well defined place where you can implement these types of generic ‘services’ in a location that can easily add endpoints (via Controller methods) or separated out as more full featured APIs. Granted this could be done with MVC as well, but Web API seems a clearer and more well defined place to store generic application services. This is one thing I used to do a lot of in my own libraries and Web API addresses this nicely. Great fit.

 

Mixed HTML and AJAX Applications: Not a clear Choice 

For all the commonality that Web API and MVC share they are fundamentally different platforms that are independent of each other. A lot of people have asked when does it make sense to use MVC vs. Web API when you’re dealing with typical Web application that creates HTML and also uses AJAX functionality for rich functionality. While it’s easy to say that all ‘service’/AJAX logic should go into a Web API and all HTML related generation into MVC, that can often result in a lot of code duplication. Also MVC supports JSON and XML result data fairly easily as well so there’s some confusion where that ‘trigger point’ is of when you should switch to Web API vs. just implementing functionality as part of MVC controllers.

Ultimately there’s a tradeoff between isolation of functionality and duplication. A good rule of thumb I think works is that if a large chunk of the application’s functionality serves data Web API is a good choice, but if you have a couple of small AJAX requests to serve data to a grid or autocomplete box it’d be overkill to separate out that logic into a separate Web API controller. Web API does add overhead to your application (it’s yet another framework that sits on top of core ASP.NET) so it should be worth it

Keep in mind that MVC can generate HTML and JSON/XML and just about any other content easily and that functionality is not going away, so just because you Web API is there it doesn’t mean you have to use it. Web API is not a full replacement for MVC obviously either since there’s not the same level of support to feed HTML from Web API controllers (although you can host a RazorEngine easily enough if you really want to go that route) so if you’re HTML is part of your API or application in general MVC is still a better choice either alone or in combination with Web API.

 

Some Issues about Web API

Web API is similar to MVC but not the Same

Although Web API looks a lot like MVC it’s not the same and some common functionality of MVC behaves differently in Web API. For example, the way single POST variables are handled is different than MVC and doesn’t lend itself particularly well to some AJAX scenarios with POST data.

Code Duplication

If you build an MVC application that also exposes a Web API it’s quite likely that you end up duplicating a bunch of code and – potentially – infrastructure. You may have to create authentication logic both for an HTML application and for the Web API which might need something different altogether. More often than not though the same logic is used, and there’s no easy way to share. If you implement an MVC ActionFilter and you want that same functionality in your Web API you’ll end up creating the filter twice.

 

Conclusion

Web API is a great new addition to the ASP.NET platform and it addresses a serious need for consolidation of a lot of half-baked HTTP service API technologies that came before it. Web API feels ‘right’, and hits the right combination of usability and flexibility at least for me and it’s a good fit for true API scenarios. However, just because a new platform is available it doesn’t mean that other tools or tech that came before it should be discarded or even upgraded to the new platform. There’s nothing wrong with continuing to use MVC controller methods to handle API tasks if that’s what your app is running now – there’s very little to be gained by upgrading to Web API just because. But going forward Web API clearly is the way to go, when building HTTP data interfaces.

AngularJS (2+) Routing on Visual Studio (2015+)

This post shows how to configure Angular 2+ Routing on an ASP.Net MVC web application in Visual Studio 2015+

Step 1 – Make sure you have installed the prerequisites

Visual Studio 2015+
TypeScript 2.0 

Step 2 – Create ASP.NET MVC Web Application

Go to Visual Studio’s File New Project menu, expand the Web category, and pick ASP.NET Web Application 

Select the template MVC:

Step 3 – Configure Angular 2+

We need now to prepare our frontend to run Angular 2+

Create tsconfig.json which is the TypeScript compiler configuration file.

<span class="js__brace">{</span> 
  <span class="js__string">"compilerOptions"</span>: <span class="js__brace">{</span> 
    <span class="js__string">"target"</span>: <span class="js__string">"es5"</span>, 
    <span class="js__string">"module"</span>: <span class="js__string">"commonjs"</span>, 
    <span class="js__string">"moduleResolution"</span>: <span class="js__string">"node"</span>, 
    <span class="js__string">"sourceMap"</span>: true, 
    <span class="js__string">"emitDecoratorMetadata"</span>: true, 
    <span class="js__string">"experimentalDecorators"</span>: true, 
    <span class="js__string">"lib"</span>: [ <span class="js__string">"es2015"</span>, <span class="js__string">"dom"</span> ], 
    <span class="js__string">"noImplicitAny"</span>: true, 
    <span class="js__string">"suppressImplicitAnyIndexErrors"</span>: true 
  <span class="js__brace">}</span> 
<span class="js__brace">}</span> <br />Add package.json file to your project folder with the below code:<br />The most important things in your package.json are the name and version fields. <br />Those are actually required, and your package won't install without them. <br />The name and version together form an identifier that is assumed to be completely unique. <br />Changes to the package should come along with changes to the version.<br /><br />
<span class="js__brace">{</span> 
  <span class="js__string">"name"</span>: <span class="js__string">"angular-quickstart"</span>, 
  <span class="js__string">"version"</span>: <span class="js__string">"1.0.0"</span>, 
  <span class="js__string">"description"</span>: <span class="js__string">"QuickStart package.json from the documentation for visual studio 2015+ &amp; WebApi"</span>, 
  <span class="js__string">"scripts"</span>: <span class="js__brace">{</span> 
    <span class="js__string">"start"</span>: <span class="js__string">"tsc &amp;&amp; concurrently \"tsc -w\" \"lite-server\" "</span>, 
    <span class="js__string">"lint"</span>: <span class="js__string">"tslint ./app/**/*.ts -t verbose"</span>, 
    <span class="js__string">"lite"</span>: <span class="js__string">"lite-server"</span>, 
    <span class="js__string">"pree2e"</span>: <span class="js__string">"webdriver-manager update"</span>, 
    <span class="js__string">"test"</span>: <span class="js__string">"tsc &amp;&amp; concurrently \"tsc -w\" \"karma start karma.conf.js\""</span>, 
    <span class="js__string">"test-once"</span>: <span class="js__string">"tsc &amp;&amp; karma start karma.conf.js --single-run"</span>, 
    <span class="js__string">"tsc"</span>: <span class="js__string">"tsc"</span>, 
    <span class="js__string">"tsc:w"</span>: <span class="js__string">"tsc -w"</span> 
  <span class="js__brace">}</span>, 
  <span class="js__string">"keywords"</span>: [], 
  <span class="js__string">"author"</span>: <span class="js__string">""</span>, 
  <span class="js__string">"license"</span>: <span class="js__string">"MIT"</span>, 
  <span class="js__string">"dependencies"</span>: <span class="js__brace">{</span> 
    <span class="js__string">"@angular/common"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/compiler"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/core"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/forms"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/http"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/platform-browser"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/platform-browser-dynamic"</span>: <span class="js__string">"Version#"</span>, 
    <span class="js__string">"@angular/router"</span>: <span class="js__string">"Version#"</span>, 
 
    <span class="js__string">"angular-in-memory-web-api"</span>: <span class="js__string">"~0.2.4"</span>, 
    <span class="js__string">"systemjs"</span>: <span class="js__string">"0.19.40"</span>, 
    <span class="js__string">"core-js"</span>: <span class="js__string">"^2.4.1"</span>, 
    <span class="js__string">"rxjs"</span>: <span class="js__string">"5.0.1"</span>, 
    <span class="js__string">"zone.js"</span>: <span class="js__string">"^0.7.4"</span> 
  <span class="js__brace">}</span>, 
  <span class="js__string">"devDependencies"</span>: <span class="js__brace">{</span> 
    <span class="js__string">"concurrently"</span>: <span class="js__string">"^3.2.0"</span>, 
    <span class="js__string">"lite-server"</span>: <span class="js__string">"^2.2.2"</span>, 
    <span class="js__string">"typescript"</span>: <span class="js__string">"~2.0.10"</span>, 
 
    <span class="js__string">"canonical-path"</span>: <span class="js__string">"0.0.2"</span>, 
    <span class="js__string">"tslint"</span>: <span class="js__string">"^3.15.1"</span>, 
    <span class="js__string">"lodash"</span>: <span class="js__string">"^4.16.4"</span>, 
    <span class="js__string">"jasmine-core"</span>: <span class="js__string">"~2.4.1"</span>, 
    <span class="js__string">"karma"</span>: <span class="js__string">"^1.3.0"</span>, 
    <span class="js__string">"karma-chrome-launcher"</span>: <span class="js__string">"^2.0.0"</span>, 
    <span class="js__string">"karma-cli"</span>: <span class="js__string">"^1.0.1"</span>, 
    <span class="js__string">"karma-jasmine"</span>: <span class="js__string">"^1.0.2"</span>, 
    <span class="js__string">"karma-jasmine-html-reporter"</span>: <span class="js__string">"^0.2.2"</span>, 
    <span class="js__string">"protractor"</span>: <span class="js__string">"~4.0.14"</span>, 
    <span class="js__string">"rimraf"</span>: <span class="js__string">"^2.5.4"</span>, 
 
    <span class="js__string">"@types/node"</span>: <span class="js__string">"^6.0.46"</span>, 
    <span class="js__string">"@types/jasmine"</span>: <span class="js__string">"2.5.36"</span> 
  <span class="js__brace">}</span>, 
  <span class="js__string">"repository"</span>: <span class="js__brace">{</span><span class="js__brace">}</span> 
<span class="js__brace">}<br /><br />Create a sub-folder app on the root folder. On this folder we need to create our typescript files: <br />- main.ts<br />- app.module.ts<br />- app.component.ts<br />- app.component.html<br />- need to create also components to each route we need. <br />On this example we need to create two components Roo1Component and Root2Component that must be declares on app.module.ts</span> <br /><br />Create your index.html<br /><br />
<span class="html__doctype">&lt;!DOCTYPE html&gt;</span> 
<span class="html__tag_start">&lt;html</span><span class="html__tag_start">&gt; 
</span><span class="html__tag_start">&lt;head</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;script</span><span class="html__tag_start">&gt;</span>document.write('<span class="html__tag_start">&lt;base</span> <span class="html__attr_name">href</span>=<span class="html__attr_value">"' + document.location + '"</span> <span class="html__tag_start">/&gt;</span>');<span class="html__tag_end">&lt;/script&gt;</span> 
    <span class="html__tag_start">&lt;title</span><span class="html__tag_start">&gt;</span>Angular2+ Routing<span class="html__tag_end">&lt;/title&gt;</span> 
    <span class="html__tag_start">&lt;base</span> <span class="html__attr_name">href</span>=<span class="html__attr_value">"/"</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;meta</span> <span class="html__attr_name">charset</span>=<span class="html__attr_value">"UTF-8"</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;meta</span> <span class="html__attr_name">name</span>=<span class="html__attr_value">"viewport"</span> <span class="html__attr_name">content</span>=<span class="html__attr_value">"width=device-width, initial-scale=1"</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;base</span> <span class="html__attr_name">href</span>=<span class="html__attr_value">"/"</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;link</span> <span class="html__attr_name">rel</span>=<span class="html__attr_value">"stylesheet"</span> <span class="html__attr_name">href</span>=<span class="html__attr_value">"styles.css"</span><span class="html__tag_start">&gt; 
</span> 
    <span class="html__comment">&lt;!-- load bootstrap 3 styles --&gt;</span> 
    <span class="html__tag_start">&lt;link</span> <span class="html__attr_name">href</span>=<span class="html__attr_value">"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"</span> <span class="html__attr_name">rel</span>=<span class="html__attr_value">"stylesheet"</span><span class="html__tag_start">&gt; 
</span> 
 
    <span class="html__comment">&lt;!-- Polyfill(s) for older browsers --&gt;</span> 
    <span class="html__tag_start">&lt;script</span> <span class="html__attr_name">src</span>=<span class="html__attr_value">"node_modules/core-js/client/shim.min.js"</span><span class="html__tag_start">&gt;</span><span class="html__tag_end">&lt;/script&gt;</span> 
    <span class="html__tag_start">&lt;script</span> <span class="html__attr_name">src</span>=<span class="html__attr_value">"node_modules/zone.js/dist/zone.js"</span><span class="html__tag_start">&gt;</span><span class="html__tag_end">&lt;/script&gt;</span> 
    <span class="html__tag_start">&lt;script</span> <span class="html__attr_name">src</span>=<span class="html__attr_value">"node_modules/systemjs/dist/system.src.js"</span><span class="html__tag_start">&gt;</span><span class="html__tag_end">&lt;/script&gt;</span> 
 
    <span class="html__tag_start">&lt;script</span> <span class="html__attr_name">src</span>=<span class="html__attr_value">"systemjs.config.js"</span><span class="html__tag_start">&gt;</span><span class="html__tag_end">&lt;/script&gt;</span> 
    <span class="html__tag_start">&lt;script</span><span class="html__tag_start">&gt; 
</span>        System.import('app/main.js').catch(function (err) { console.error(err); }); 
    <span class="html__tag_end">&lt;/script&gt;</span> 
 
<span class="html__tag_end">&lt;/head&gt;</span> 
<span class="html__tag_start">&lt;body</span><span class="html__tag_start">&gt; 
</span>    <span class="html__tag_start">&lt;my</span>-app<span class="html__tag_start">&gt;</span>Loading App&lt;/my-app&gt; 
<span class="html__tag_end">&lt;/body&gt;</span> 
<span class="html__tag_end">&lt;/html&gt;</span> <br /><br />Angular will launch the app in the browser with our component and places it in a specific location on index.html.

Web API 2.0

ASP.NET Web API 2 has been released with a number of new exciting features:
 

1. Attribute Routing

Along with convention-based routing, Web API 2 now supports attribute routing as well.

In case of convention-based routing, we can define multiple route templates. When a request comes, it will be matched against already defined route templates, and forwarded to specific controller action according to matched template.

You can see the following default route template in routing table for Web API:

This routing approach has benefits that all routing templates are defined at one common location but for certain URI patterns, it really becomes difficult to support (like nested routing on same controller).

With ASP.NET Web API 2, we can easily support above mentioned URI pattern and others as well. Following shows an example of a URI pattern with attribute routing. URI Pattern –> books/1/authors


2. CORS – Cross Origin Resource Sharing

Normally, browsers don’t allow making cross-domain calls due to same-origin policy and we know that. So, what exactly is CORS (Cross Origin Resource Sharing)?

CORS is a mechanism that allows a web page to make an AJAX call to a domain other than the domain which actually rendered that specific web page. CORS is compliant with W3C standards and now ASP.NET Web API has support for it in version 2.

 

3. OWIN (Open Web Interface for .NET) self hosting

ASP.NET Web API 2 comes with a new self hosting package i.e. Microsoft.AspNet.WebApi. OwinSelfHost.   According to http://owin.org/

OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.

So, according to above description, OWIN is an ideal option for self hosting a web application in a process other than IIS process.

There are a number of OWIN implementations like Giacomo, Kayak, Firefly etc. available (some may be partial or outdated) but Katana is the recommended one for Microsoft servers and Web API frameworks.

 

4. IHttpActionResult

Along with the existing two approaches of creating response from controller action, ASP.NET Web API 2 now supports another way of doing the same. IHttpResponseMessage is basically an interface which acts as a factory for HttpResponseMessage. It’s very powerful because it extensify web api. Using this approach we can compose any specific type of response.

 

5. Web API OData

The Open Data Protocol (OData) is actually a web protocol for querying and updating data. ASP.NET Web API 2 has added support for $expand, $select, and $value options for OData. By using these options, we can control the representation that is returned from the server.

  • $expand: Normally, response doesn’t include related entities if we query an OData collection. By using $expand, we can get related entities inline in response.
  • $select: It’s used if we wanted to include subset of properties in response instead of all.
  • $value: It allows to return raw value of the property instead returning in OData format.

 

 

 

AngularJS Best Practices

Refactoring Existing Code to Angular

Start Small

Regardless of the type of code you’re refactoring, it’s usually best to start with a small component. It doesn’t always make sense to move everything into using some other library just because you can, but rather just change things as you need to develop new features or fix bugs. The simplest way to start is by taking a part of the code and replacing it with an Angular controller. Take away any code that modifies the DOM, and instead build it into the markup using Angular’s databinding features. You’ll definitely encounter cases where you need to access some more general code when doing this, which is a perfect case to move the code into a service. Then, it’s very easy to inject it into your controller.

Organizing Code

It’s usually a good idea to keep things simple. When you start, just create a page-specific angular module. This is probably quite obvious if you’re working with a single page app, but in a case where your app has traditional page changes, keeping modules on their own pages for starters is a good idea. As you keep adding things into the module, you’ll probably start seeing things that should be shared between controllers. In a case like that, you should move the code into a service.

Eventually you’ll start seeing cases where you need the same functionality in different modules. When this happens, create a base module and put the shared things there. You can then add a dependency to the base module into your page-specific modules.

Dealing with the DOM

You can easily move much of legacy DOM handling code into Angular simply by using Angular’s builtin directives and databinding features. However, in the likely case that you have used some jQuery plugins or done some other slightly more involved DOM trickery, things may be a tiny bit more difficult to sort out.

The most straightforward things can easily be wrapped into a directive. Sometimes the only thing you need to do is take the jQuery (or other) function call, wrap it in a directive and call it a day. For anything nontrivial, it’s usually worth checking out whether you can simply plug in Angular UI and be done with it. Even if that’s not the case, you can use their code as an example on how to do more complex plugin integrations or such into directives.

Working with Legacy Code
Especially with large applications, it’s often not feasible to move everything into Angular at once. You’re going to need to access your Angular services from some of the legacy code, and you’re also going to need to be able to respond to changes that happen via legacy event handlers inside your Angular code.

Copyright © All Rights Reserved - C# Learners