Developing Angular2 Dart Asset Services, Part 3

Continued from Part 2

This article continues an effort to externalize content assets for a fictitious app. In Part 1 and Part 2, we developed an external HTML content repository and an Angular service to retrieve these assets. But our fictive scenario requires that we include not only external HTML but photo assets as well. In this article, we’ll provide that support in a similar strategy as was done for HTML content.

I’ll demonstrate how, relying on Dart and specifically Dart Angular’s strengths, we can easily automate much of the tedium of dealing with photo assets, including license compliance and converting raw images to production web assets.

Photo Service Interface

Just as with our HTML content provider, our interface of a Photo provider is simple:

PhotoService interface

The getPhoto method expects a PhotoId, which is simple container:

PhotoID: a reference to a photo

and returns a Future Photo:

Photo: a container for photo asset info

Image License Compliance

We know our app will need to use external images, but we also understand that most images are provided under license which may come with obligations on our part. Commonly authors must be attributed or licenses linked. Our app must abide by these rules, and therefore the image asset provider must supply this information to our app.

Hence, the Photo class above contains an Attribution, which dictates how attribution should be handled:

Attribution: a container for attribution details

Note that information about the specific license is not included. Our app does not particularly care what the license is, only how any specific photo must be attributed. Later in the article, we’ll handle the translation of specific licenses into attribution details further down the stack (in fact, external to this app).

Client-based Photo Service

Our photo provider implementation needs to provide a Photo, meaning our implementation must determine the photo URL and attribution details. Starting with the URL part, we implement a simple solution:

ClientPhotoService implementation, pending attribution support

Following the logic in getPhoto, we are simply constructing a URL based on the provided photo identifier and category. There’s no need to physically fetch anything, since a web browser is very capable of fetching external image resources. We simply provide a URL and rely on our asset repository to conform to this structure.

We will have to fetch the licensing information via network request, however. We dictate a convention that our asset source include a JSON license file, with a .license extension, for each photo. The format of the JSON is proscribed per the following example:

Sample .license info for photo

With this convention defined, we update the ClientPhotoService implementation to retrieve this information and instantiate the correct attribution details:

ClientPhotoService, including attribution

The implementation of _getPhotoAttribution is similar to the ClientContentService implementation of getContent discussed in Part 2. We fetch a remote file, in this case the JSON license file, using an injected Client. Instead of sanitizing response as we did for HTML content, we simply decode the JSON and assign Attribution fields parameters from the decoded data.

Our app is now free to inject and use this photo asset provider. Our app will decide exactly how to properly attribute photos based on the simple Attribution instructions provided from the service.

An External Photo Repository

While technically we’ve completed our obligations to our app, we don’t actually have any photo assets to show or test with. We can construct alternate providers for use in testing (there are a few in the repo), but we can also make our own photo repo for use with ClientPhotoService. However, resizing and cropping photos and hand-writing JSON certainly isn’t our style, so what can an impatient Dart author do?

Recall in Part 2 we built a HTML content repo that would allow copywriters to author in Markdown. Our content repo, with some custom transformers, would automatically convert these markdown files into production-ready HTML. We’ll use a similar approach here, allowing our photographers to simply store raw images and specify basic licensing info. Our repo will take care of the work of transforming these into production-ready assets.

To start, we create a new repo and define our photo assets with all pertinent info in a yaml file assets/image/section_photo.yaml. An excerpt:

Sample yaml defining two photo assets

Here we’ve described two input photo assets, along with our their desired output name and any pertinent licensing info.

We now define the licenses used above, including the necessary attribution requirements for each. Example:

There are additional licenses and some helpers, such as a LicenseFactory, that I omit here for clarity. See source for more detail.

Finally, we create a Dart bin script to generate our production assets and license JSON from the above yaml. Our script will loop through each entry in the yaml, for each performing cropping/scaling/resizing using the ImageMagic convert binary and writing the JSON license file.

The example above is fairly simple, but the script could be updated to apply effects, watermark images, modify image metadata, etc.

Now, if we place source images in assets/photo/section and update our section_photos.yaml accordingly, then when we run pub bin/gen_section_photos our processed images and JSON license info will be deposited into the web/content/images/section directory, just like our photo asset provider expects.

We can then pub serve this repo for development use or, for production, simply copy our generated assets to a static web server.


In these three articles, I’ve illustrated how relying on the strengths of Angular Dart and Dart in general can greatly boost productivity and flexibility.

Dart and Angular Dart’s features, including dependency injection, futures, transformers, and robust web-centric libraries make web development fun again.


These articles were based on work I did creating inTallinn, a visitors’ guide to my home city Tallinn, Estonia. See the full source code of inTallinn, which expands on the contents of these articles.

Originally published at on February 13, 2017.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mike Hoolehan

Software dev, camper, baseball player; an American in Tallinn, a long way from Terre Haute