Saturday, February 8, 2014

Adventures in Angular Directives

If you’re reading this you probably know that “directives” are the Angular glue that binds the browser DOM to your JavaScript. Familiar examples include “ngModel”, “ngBind”, and “ngRepeat”.

Angular ships with a lot of glue but the team can’t cover every possible scenario and they don’t want to try. They expect us, the authors of Angular apps, to extend Angular with our own custom directives.

There’s a lot of great online material about directives – how they work and how to write them. People obsess so much about them that you’d be forgiven for thinking that Angular is all about  writing your own directives.

Please don’t think that! You can go miles and miles without ever writing a single directive. There’s an excellent chance someone has already written the directive you need; search the web first.

Angular is simple and easy to use. We seem to be doing our best to make it look difficult by glomming on to its most complex feature. Really people … let’s not scare newcomers away.

I’ve been living this advice for a long time. I think I’m pretty decent with Angular and I’ve managed to avoid writing custom directives for the most part. Those that I did write were dead simple and not worth crowing about.

I finally stumbled into the need to go beyond rudimentary directive construction with the Breeze “zValidation” directive. This directive taps into an entity’s validation errors collection and, if there are validation errors, will display them on screen in a red box next to the errant property. If the property is required it also displays a required indicator.

Folks like it but they want richer display options. For example, they’d like the directive to display a label for the property in a well-defined location and change the label’s styling when the property is required.

You couldn’t do that with my first version of this directive (which was already the hardest directive I’d ever attempted). I felt it was time to use the dreaded Angular transclusion.

Hard to believe that transclusion is a real word but it is … at least it is in our strange technology world. Ted Nelson coined it in 1963.

Unfortunately, transclusion didn’t work the way I expected. I described my issue on Google Groups under the title “Can't Transclude an Input Element”. This lead to a series of helpful exchanges with the Angular community that resulted in a plunker code sample  that describes a path to a solution. I’ll soon rewrite “zValidate” to take advantage of what I learned.

Meanwhile, I offer my lessons learned by reproducing below the plunker’s readme.md file that provides the details of the journey and its resolution.


You Can't Transclude an Input Element

An attribute directive that will transclude a <div> won't transclude an <input> element as seen in my original plunker.

I can transclude a <div> or <span> that contains an <input> but not the bare <input> itself.

Explanation

I learned from the community that I was mistaken about how transclusion works. Transclusion copies the contents of the container element, not the element itself.

My mental model had been that of ngRepeat in which the element that carries that attribute is included in the repeated (and transcluded) material.

That isn't how it works when we apply transclusion in our own directives. For us the element carrying the directive attribute isexcluded.

Solutions

A series of plunkers from the community made all of this clear. Alternative approaches involved a transclusion function; see this one from Umi and this one from Sander.

Even these were overkill for this particular example because we weren't asking Angular to do anything with the material in the template. Under such hothouse circumstances, there is no need for transclusion either ... just some simple template manipulation as seen in this plunker from me.

However, my goal isn't really that simple. My goal is to enable wrapping an input control in more complex HTML that can display validation error messages, required indicators, and labels. In all such decorations we would ask Angular to fill-in-the-blanks withdata bound to the scope.

The "ultimate solution"?

Ok ... nothing is ever final. But this one demonstrates the essential mechanics for what I want to do.

It employs a compile phase to compose the template around the target element. This happens before there is a scope so it can't do any data binding. The advantage of performing this work in the compile phase before binding data values is that we only perform it once within an ng-repeat block, a fact demonstrated in the this example in the last textbox. Getting these template manipulations out of the way early might improve performance when displaying a long list.

The compile function returns a link function which Angular calls for each data bound scope. This is when Angular fills-in-the-blanks with actual values for each scope instance as illustrated in the textbox within the ngRepeat.

You can manipulate the output HTML in the link phase as well, as seen here:

element.find('mark').text(linkCounter)

where the contents of a <mark> tag is filled by the local value of the linkCounter.

This example directive also demonstrates the utility (and occasional necessity) of a local child scope, enabled by thescope: true setting.

Without that setting, the counter would become a property of the outer scope. We want this counter to update for each binding. If it were not a child scope the link function would increment the one-and-only counter property and we'd see that same value in all of the bindings. Perhaps as bad, we risk overwriting a property of the outer scope called "counter" that we had no business touching. Comment out the scope setting to see what I mean.

Note that we must use the child scope, not the isolate scope. The templated element will surely bind to a value in the outer scope (e.g., the textbox value); an "isolate scope" would shield that value, resulting in an empty binding. Replace the scope setting with scope: {} to see what I mean.

Todo

Of course this isn't the "ultimate solution". I wouldn't bake the template into the directive. I'd want it to be configurable perhaps with a template function option. I'd probably want the developer to be able to set a default template during the Angular "config" phase.

These thoughts are "out of scope" (yuck yuck) for the issued addressed in this example.

Wednesday, January 8, 2014

Song of Myself

With sincere apologies to Walt Whitman, I commend to you an autobiographical sketch recorded with Shawn Wildermuth in late December 2013 as part of his “Hello World” series of developer interviews.
It covers my early years as a Knucklehead Programmer which was kind of like Wolf of Wall Street minus the money, blow, and hookers.
Shawn and I do have a darned good time talking about programming in the 70s/80s (APL, big iron, life before PCs and RDMS), people who changed our lives, and what we can do to nurture the developer community.
Go subscribe to Shawn’s series so you can listen to a great cast of developer characters talk about how they got started in this game.
I wonder if Shawn will interview himself :-)

Extra links

Shawn included a few links on his page but I thought you might like a few more with my memories attached.

Steve Dunwell

Steve Dunwell, the IBM Fellow, lead architect and manager on the pioneering STRETCH computer is remembered in this article, “Return of the prodigal son: the rehabilitation of Steve Dunwell”. His passion for educational computing made my introduction to computing possible at a time when “computers in the schools” was almost inconceivable.  

APL – A Programming Language

APL, my first programming language and my source of income for two decades. Here is Conway’s Game of Life in a single line of “write once, read never” APL: Look Ma! No Loops!
We loved it.  We owned our own 16Kb slice of an IBM/360. No overseers. No types, No compiler. Cult language. We rocked.
My first “computer” was actually an IBM/360 connected by a private telephone line and acoustic coupler to this 2741 terminal, a modified Selectric typewriter.
clip_image001 The Selectric Typewriter printed with a typesphere that rotated and tilted for each letter before striking a ribbon and the paper behind it (see video). IBM made a special typesphere to print those weird APL characters: clip_image002 My first green screen terminal was a 3270 display. It was roughly the size of a foot locker and must have weighed  more than 50 pounds. The manual was over 100 pages. The character set was IBM’s own EBCDIC; ASCII was an option but I don’t remember seeing ASCII actually installed. A bigger, heavier color version arrived with the 3279 some years later:  

History of the Relational Database

I talked some about the early history of the Relational Database when it was fresh and exciting and how it had to overcome the predominate database architectures of its day (architectures we’d now categorize as “NoSQL” ). Did you know that it was invented at IBM by E.F. Codd. and that IBM suppressed it for almost a decade? Read all about it in this fascinating interview with C.J. Date.  It’s a PDF. You’ll learn that Codd wrote an early relational database query language in APL (p.28) and that he hated SQL.  

Community Memory

I talk briefly about my time at Community Memory one of the earliest experiments in social networking. The first Community Memory terminal, at Leopold's Records, Berkeley, CA, 1973. Photo taken by and for the Community Memory Project, first published in the Resource One Newsletter, April 1974, and originally posted to the web in 1996 by Mark Szpakowski The technology was a bunch of teletype terminals in Berkeley laundry mats and record stores, connected by phone lines (no internet). What fascinates me to this day was how CM’s vision of social change through social networking both did and did not happen. You get some sense of that from this BBC article “Hackers and hippies: The origins of social networking” And that’s enough of that!
















Friday, January 3, 2014

Hooray for Durandal (nextGen)

Stop what you’re doing and learn right now about the next generation of Durandal. Watch the video (just 25 minutes) to see how intuitive and easy it is to build a nextGen Durandal application. Then push the “Back This Project” button and help fund it.

Full Disclosure: I have no connection with this project. I just like it a lot. And I put my money where my mouth is.

At IdeaBlade we’ve been big fans of the Durandal presentation framework for building Single Page Applications (SPAs) in HTML and JavaScript. Durandal has served us (and our clients) well for over two years and today’s Durandal deserves its place among the top SPA frameworks. There are lots of ways to learn about it, none better than John Papa’s Pluralsight course, “Single Page Apps JumpStart”.

Durandal’s author is Rob Eisenberg, known to many of you as the man behind the Caliburn.Micro. Rob’s been at this game a long time. I think he must have built and re-built three or four of these presentation frameworks by now, learning and improving with each iteration. He’s didn’t just wake up yesterday and decide he could write a better framework than everyone else. He’s been writing better frameworks than almost everyone else.

I took him very seriously (and got seriously excited) when he told me about the next generation of Durandal for ECMAScript 6 browsers that are just around the corner. I’ve been tracking his new designs and his progress for several months. This next version of Durandal is going to be great.

What’s so great about it? What’s distinctive about it? Rob has his inventory of laudable features (and its impressive). Here are some of the aspects of nextGen Durandal that I love … and that have no equal among alternative frameworks:

  • Convention over configuration – I hate writing and maintaining “switch board” code to connect FooViewModel to FooView and FooRoute etc. I want to say “Foo” and be done with it … until and unless I have a compelling reason to break convention.
  • Customizable conventions – Rob makes good choices but I’m free to define my own.
  • Page life-cycle – Durandal has baked in understanding of the birth and death of “pages” so I don’t have to make up my own hacks to ensure that new pages are initialized on creation and cleaned up on destruction.
  • Asynchrony throughout – Need to wait for the user to confirm or cancel before moving off the page? That’s easy in Durandal because asynchrony is plumbed through the page life-cycle and everywhere else. Dynamically load optional modules on-demand? Easy.
  • Diagnostics – With debug mode turned on the console tells me exactly what choices Durandal is making for me as they happen. I can tap into that logging pipeline with my own diagnostics.
  • Write less, do more – You all know what I mean. We all want to write less code. That’s the motherhood and apple pie that every framework promises. They usually deliver something else. Check out the nextGen Durandal sample video and tell me what other technology is that clear and concise.

Yes, there are other presentation frameworks out there and I like one or two of them as well. Why get involved with the Durandal project, even if it is great? Shouldn’t we just back “the winner”?

I don’t think we can afford to just sit here and let any one of the frameworks dominate. That’s not good for the web. It wasn’t good when IE6 owned the browser world even if it was the best browser at the time. It won’t be good for the web if today’s favorite owns this presentation framework space either. Frankly, no one has nailed it yet. They all make me itch. It’s too early to declare a winner.

We need to encourage real competition … by which I mean truly well done, distinctive approaches to our common application building problems. Durandal is a worthy competitor. It fosters ideas and techniques that must find their way into our application development practices. Durandal deserves your support. Go give it some love.

Sunday, March 3, 2013

Blogging from an iPad with Blogsy

My BFF Peggy is traveling to Morocco for two months.

She wants to blog about it. Who wouldnt?

She's facing some challenges. First, Her only computer ... an iPad mini. Typing a post on glass is not for me. I'm writing this post in that fashion and I won't last long. "Get a keyboard" I say. Which one? Don't know. Maybe someone can recommend one.

Second challenge: she has never blogged before. The process has to be simple. No messing around with HTML or CSS.

Third challenge. She writes. She won't be content with posts consisting of photos and captions. She is not a Facebook person. She will be reflecting on her experience ... You know ... Like with real words (see keyboard comment above). So FB is out. So is Tumblr

Fourth, without asking me, she picked Google's Blogger. Hey, I happen to use that for this blog. Wouldn't call it the easiest choice.

Good news: after playing with it on my wife's iPad, I'm feeling pretty confident in asserting that, you're going to blog on Blogger from an iPad, Blogsy is the app to use. I'm writing this post with Blogsy.

It formats!

Of course it should. What's nice is that it was intuitive from menu bar.

Picture ... or it didn't happen

 

Great features. Great integration with wide variety of resources. Easy to use (for me; I hope easy for her too) after you watch the excellent video on dragging and dropping.

Here I'm inserting a picture of my dog which happens to be on this iPad. He fits right in. I can wrap text around him too.

And then I can resume with my post after the photo. This was easy to do by dragging and tapping.

Enough typing on glass. If you're reading this you know I published successfully ... and that it ain't gonna be so bad blogging from Morocco on an iPad.

Monday, February 25, 2013

The Breeze Server: "Have it your way"

BreezeJS is a 100% JavaScript client library. It can work with any backend that speaks HTTP.

It's hard to get that message across when most Breeze samples demonstrate a Breeze client talking to a Web API controller with Entity Framework and SQL server behind it. Understandably, some people believe that Breeze only works with Web API, EF, and a SQL database. We need more samples to show alternatives. We're working on those.

In the absence of those samples, please sing along with me now, the unforgettable "Have it your way" jingle from the 1976 Burger King commercial. Curse me later for your inability to get that song out of your head.

For the hard of hearing, I'm reprinting an email I sent recently to my web developer friends on this subject.

Technorati Tags: ,,


I'd like to clear up some misconceptions about BreezeJS regarding the relationship between data on the client and data on the server. Want the gist? Head straight to the Summary at the end.

BreezeJS is a library for building CRUD applications in client-side JavaScript and HTML. A Breeze application depends on a JavaScript entity model defined for the application domain as that domain is understood on the client.

How closely the client entity model corresponds to a model on your server is entirely up to you. The client-side BreezeJS is happy to accommodate you!

For many developers, the independence of the client and server models is a matter of principle and they will go to great lengths (and write a ton of server code) to demonstrate and defend that principle.

Personally, I'd rather write less code. The hardest part of my application will be building a tolerable UI that meets the application requirements for functionality, data integrity, security, and usability. That's a tall order. I'm not eager to do more than I have to. Moreover, I would gladly postpone some heavy coding decisions today if I am confident that I can change direction tomorrow without a massive rewrite. That perspective informs my preferred Breeze development path. Your perspective may be different.

As I said, the Breeze client entity model need not correspond to any server model. But it's a heck of a lot easier when it does. We paved a rose-petal path for the .NET developer who is happy with a Web API service talking to Entity Framework for data access and mapping to a POCO entity model. Breeze.NET components make it easy to expose EF metadata and IQueryables to a Breeze client and, yes, they make it easy to open the kimono to the client. Fortunately, with just a little effort you can show a lot more discretion and remain productive.

I am unashamed to take this path myself. I have no desire to waste valuable customer time and money moving data into and out of DTOs "on principle". I am reluctant to “pollute” the server with hundreds of controllers each with 4 or more methods.

I am not kidding about the consequences. The typical business application has a minimum of 200 domain model types. 90+% of the time the shape of the data I'm sending over the wire is the same as the shape of the entity in my business model. An Order in the database often looks like an Order in the domain model and the Order in the domain model probably look like an Order on the client most of the time. When such an entity meets the JSON.NET serializer it might as well be a DTO.

When the entity type is simple, it is likely to have the same shape in every layer. In my experience, models are dominated by relatively simple types and types with no serious privacy concerns. There are usually a few hairy ones that need close attention; the vast majority to not merit that much love.

I know how to guard queries so that the right people get the right data. Of course I always inspect the change-set data coming from the client to make sure they actually should be saved before I tell my persistence machinery to save them. This essential effort is no more complicated or onerous with Breeze than any alternative you can propose.

You are welcome to disagree. I know that some of you do disagree. Fine. Have it your way. Replace the database with your favorite backing store. Create DTOs. Add more controllers with more fine-grained query and save methods to do exactly what you want. Don't like $expand or $select? Deny them! Can't figure out how to make IQueryable work for your DTOS? Don't use IQueryable. BreezeJS is happy to accommodate you!

Of course you'll be writing more code on the server. You've signed up for all the mapping, the DTO files, the controllers, layers, duplicate guard logic, and the whole nine yards. In no time you'll be praising an auto-mapper that automate away the tedium that, from my perspective, you never needed to endure in the first place. You'll paper your walls with intricate architecture diagrams and reams of API documentation. Good luck training your successors. Knock yourself out. BreezeJS is happy to accommodate you!

Realize that your server-side choices may oblige you to write more code on the client too. Most developers really like the Breeze LINQ-like style for writing ad hoc queries (a staple of LOB apps). Breeze translates these queries into OData URL query syntax before sending them to the service.

An OData service knows what to do with that syntax. A Breeze Web API ActionFilter can apply that syntax to your controller's IQueryable methods … if they exist and to the extent that they support the range of options supported by OData query syntax.

Don't like that syntax for your service? If your service API doesn't want to play, then your Breeze client shouldn't make those requests. The Breeze "EntityManager" can make a bare resource request to any HTTP endpoint. You can easily take on some simple data parameters if your service knows how to handle them. If you're more ambitious, you can replace the Breeze AJAX plugin ($.ajax by default) or write your own dataservice adapter. BreezeJS is happy to accommodate you.

When the server responds, all that matters to BreezeJS is that the response payload contains JSON data. When Breeze sees objects that it recognizes as entity types, it turns those object into entities and caches them. But the data can also be plain old JavaScript objects.

Yes, I frequently send non-entity data to my Breeze app too. I make liberal use of projections when I don't need entities. Sometimes I write the projections on the client; sometimes I write them on the server. When the shape of a client entity doesn't align well with the shape of a server-side business entity, I may switch to a DTO for that particular case. I won't do that if I don't have to. I know that I can do it whenever I want to.

You'll get more Breeze benefits if the objects in the query result payload actually are entities. Breeze enriches entity objects with data binding support (Knockout, Angular, Backbone), validation, change tracking, and whatever custom properties and behaviors you've defined for objects of that type. Breeze caches entities and you can ask it to serialize part or all of a cache to local browser storage for offline and intermittent connectivity scenarios.

How does Breeze know if the data objects are entities? It looks up their accompanying type names in its MetadataStore. What's in the store? EntityType definitions that describe data properties, navigation properties, validations, and custom behaviors. “Custom behaviors” are JavaScript methods you add to the metadata that describe the client-side EntityType. These methods may duplicate logic you have in a server-side entity model. More often they are application logic to improve the user’s experience of the entity.

Where did that metadata come from? Well, the easy way to get metadata on the client is to ask the server for it. Breeze accepts OData metadata. Breeze also accepts an extended form of OData metadata that you can generate with Entity Framework … another benefit of allowing the client entity model to be shaped like your EF domain model.

But you don't have to get your metadata from the server and the metadata don't have to correspond to any particular server-side entity model. You can create the metadata entirely on the client if you wish (as we show in our "NoDb" sample). BreezeJS is happy to accommodate you.

If you want Breeze to materialize your JSON data as entities, the metadata do have to match the "service model" exposed through your service. This service model does not have to be an entity model. It is simply the collection of "types" that you serialize to the client in response to API calls. That service model could consist entirely of DTO types … if that's how you want to roll. It's just more code, right?

I suppose you could send any damned thing over the wire if you were willing to catch it and parse it yourself. You can create entities on the Breeze client out of data from any source … and make them appear to have been queried entities. That's how I construct test entities for my automated tests. It's just more code. BreezeJS is happy to accommodate you.

Finally, there is the matter of saving client-side changes. The easy way is to ask Breeze to detect all pending changes (adds, mods, deletes) to all kinds of entities (e.g., orders and line-items) … bundle them up and send them to the server as a change-set. Breeze.NET helpers on the server give you ready access to the bundle so you can inspect it, reject it, modify it, map it … as your heart desires. If using the vanilla Breeze.NET EF helper, the bundle will be saved as a single transaction.

Alternatively, you can cherry-pick the entities to save in a bundle.

Got your own save commands, Mr. CQRS? It’s easy to pull sub-graphs from the client cache and shape your own command payload.

Btw, you can have as many separate caches (separate “EntityManagers”) as you like, each of the isolated from the others. It’s easy to flow entities across caches (e.g., reference lists for dropdowns) so you don’t have to go back to the server all the time. I often use separate caches for different tasks, e.g., “sandbox editors”). BreezeJS is happy to accommodate you.

Summary

My life as a developer is easier when I have the same EntityType shapes, end to end, and use Web API + Entity Framework to make it so. It can be almost as easy if the service is an OData service

I'm not worried about so-called tight coupling of the client to the server. I'm building CRUD apps. 9 out of 10 times the reason I'm changing the server-side entity model is in response to a business requirement affecting the client. I'm going to be making changes on both sides anyway in lock-step fashion. And … as I said … I can break the symmetry any time at any point in the model without tearing down the whole house.

But If you want DTOs everywhere, all the time, have at it. Breeze can still help you on the client with data binding support, validation, change-tracking, and caching.

BreezeJS is happy to accommodate you.

Wednesday, October 17, 2012

Add the Visual Studio Command Prompt to VS2012

Several times this week, I wanted to launch a Windows command prompt (not the VS Command Window which is different) while in Visual Studio 2012. More specifically, I wanted to open the command prompt in the directory of the item I had selected in Solution Explorer. I swear I could do that in VS2010 but I can’t find that in VS2012.

I gave up and did a two step dance:

  1. Right-click selected folder | “Open Folder in File Explorer” [alternatively: “Open Containing Folder”]
  2. Ctrl-Shift-right-click | “Open command window here”

That works for most purposes although I don’t benefit from the VS-specific environment variables.

Then I stumbled across an old blog post by V K Sumesh (2008) that describes how to add the Visual Studio Command Prompt (VSCP) to the tools menu. That’s worth a read for background. I’ve updated the steps here for VS 2012 and to suit my preferences.

Add VSCP to the Tools menu

  1. Tools | External Tools …
  2. Click [Add]
  3. Title: Command Prompt
  4. Command: C:\Windows\System32\cmd.exe
  5. Arguments: "%programfiles%\Microsoft Visual Studio 11.0\Common7\Tools\vsvars32.bat"
  6. Initial directory: $(ItemDir)
  7. Click [Move Up] to position the command (I put mine at the top)

In step #5 I’ve specified vsvars32.bat, a batch file that supplements the Windows environment variables with environment variables for the .NET framework tools.

In step #6 I picked the “Item directory” because that’s my preference but the dialog offers other choices which may suit you better.

Here’s what it looks like before I click [OK]

VSCP

Use it

  1. In Solution Explorer select the folder or item where you want the command window to open
  2. Tools | Command Prompt

Hope that helps. Let me know if there’s a better way.

Update

The “Open command prompt” feature that I remembered from VS2010 came by way of the Microsoft “PowerCommands for VS 2010” extension.

Apparently the 2010 extension works for VS2012 as well. Take note: there are a ton of features in that extension, many of them already in VS2012. I was worried about redundancy and bloating my context menu with ever more rarely used options. But it seems well-behaved and you can disable features you don’t want via Tools | Options | PowerCommands. It’s a worthy alternative to the technique I described above.

Tuesday, October 16, 2012

Update a NuGet package with MSBuild

In this post I’ll show you how to add a prebuild MSBuild target to your project that updates a NuGet package in the project when you rebuild.

Background

We ship a zip file of BreezeJs samples . Some (soon to be all) of them rely on a NuGet package to supply the Breeze JavaScript files and other dependencies.

Breeze changes regularly (for the better we think) and so must the NuGet package version.

Our sample solutions are set to restore all NuGet packages so that we don’t have to ship them as part of the zip. Unfortunately, the “packages.config” file that identifies the BreezeJs NuGet package is stuck with the old version. Package restore simply grabs the old version of that package.

We could not find a way to markup the items in the packages.config so that NuGet restored the latest version of the package. It always restores the exact version identified in package.config.

We don’t want to modify those samples every time we update the NuGet package. We want the samples to update to the latest BreezeJs automatically.

We don’t want to update every package in the solution; just our BreezeJs package and its dependencies.

Solution

We added a prebuild target to the bottom of the project file. The target invokes nuget.exe from the command line, telling it to update only our package (“Breeze.MVC4WebApi”) and its dependencies.

We know that nuget.exe is in the project sibling “.nuget” directory because that’s where the package restore facility puts it.

Here’s our target:

<Target Name="BeforeBuild">
  <Exec Command="&quot;$(SolutionDir).nuget\NuGet&quot; update &quot;$(ProjectDir)packages.config&quot; -Id Breeze.MVC4WebApi" />
</Target>