In the Global markets, the ability to present your application in the users native language is crucial to its success. Angular Translate provides a simple API that can be used to build multilingual AngularJS applications quickly. In this demo, I will create a single page with two languages.

Wire Up

Before you begin, you will need the latest stable versions of angular.js and angular-translate.js in your scripts.  Then, you may declare angular-translate as a module load dependency.

From here, setup a config function for your module and inject $translateProvider.  If you do this, it will create the translation table at configuration. This allows the angular-translate to access the components as soon as they are instantiated. The $translateProvider tells your app which language to use and shows the app the language tables.

Once angular-translate is wired up, you need to build the translation tables inside the configuration phase and specify the default language.  Any language, which you plan to support, needs a translation table.  The table consists of json key value pairs.  The key is the id and the value is the string value of your translated text.  The function preferredLanguage() specifies the default table if no matching language is specified.

Changing the Language

Changing the language at runtime is also very easy.  In your controller, inject the $translate service and set the function, $translate.use(), to the value that you would like to use.  Of course there are many other ways to decide the default language besides clicking a button.  You may want to base it off the browser culture or possibly a user cookie.  But for simplicity, we will manually set it.

In this example, we have two buttons.  One button is for for English and the other button is for Spanish. Each include click events that call the changeLanguage() function.  When the function is called, the language key is set to the hardcoded value.

Tagging Text for Translation

Tagging the text for translation can be done with the angular-translate filter, directive or service in the controller. As you can see in the above example, there is an attribute in each button called translate.  That is the angular-translate directive.  It will render as the translated text inside the tags.

Tagging text with the filter can be done by entering the translation key inside the double curly brackets with the translate filter. Angular-translate will know to render the correct value at runtime.

When using the service to translate text, you need to inject $translate in the same way we did when changing the language.  You may then call the service and pass the translation id.  The service is based on promises. If you are not familiar with them, this article may be helpful.

http://www.dwmkerr.com/promises-in-angularjs-the-definitive-guide/

Angular-translate also allows multiple keys to be passed in a single promise.

BlogGiphy

Sanitation

One issue you may notice is a console error about sanitation. You will need to definitely address this issue.

Console Error

Your site may be vulnerable to attacks unless you set up a sanitation strategy.  It is possible for output to not escape properly, which allows hackers to attack your site.  View the site below for more information on sanitation strategies.

http://angular-translate.github.io/docs/#/guide/19_security

Extensions

There are many beneficial extensions for angular-translate that will allow for asynchronous loading and lazy loading. For more information on asynchronous/lazy loading, view the below link:

https://github.com/angular-translate/angular-translate/wiki/Asynchronous-loading

Additional Resources

As you can see, angular-translate gives developers a fast, easy way to setup translated text for your website or application.  But this was just the tip of the iceberg, check out their guide and API for a full list of features.

https://angular-translate.github.io/docs/#/guide

Get The Job That You Want!

Trying to find a job fresh out of college is hard, and I hope my recent experience will help you find the job that you want. I see some graduates snatch up the first job offer that they receive while other graduates are not able to find a job that they want, so they settle for a job that they really do not want. I graduated from college over a year ago and a few of my friends see how happy I am with my job. They often ask me, “How were you able to find such a good job with your background.” When they mention my background, they are referring to the fact that I graduated from a small college with no work experience. I believe that there are three steps to attain your dream job:

  • Enjoy what you are doing
  • Be passionate about it
  • Practice what you care about

Enjoy What You Are Doing

The first and most obvious step to obtaining the dream job is to enjoy what you are doing. You will be working 40-hour weeks for the next 30 plus years of your life, so make sure that you like it. To be more specific with my career path in software development, what will excite you? Video game development, Web site development, mobile development, etc. There are many things to think about when pursuing a career in software development. What languages do you want to use C#, Java, C++? When I graduated from college, I had no idea what I wanted to do with my Computer Science degree besides programming. After a month of submitting applications to almost every associate/junior-level position, I finally received my first offer. I was so excited to receive a callback, but then after discussing what I would really be doing with this company I decided to turn it down. In the beginning, I would receive six months of training with them and then start working as a tester. The position was also with a huge corporation, so I feel I would have been treated like an assembly worker on a line doing the same thing every day. After this offer, I decided to only apply to small businesses that used C#, which was the first language I was taught in high school and was my personal favorite.

Be Passionate About It

The more passion you have about something, the easier it is to get excited and do it well. Passion is something that your employers want to see from you. Passion shows your eagerness to continue learning and expand your horizons. Technology is evolving fast with new languages and practices are constantly coming out. It is great if you have the willingness to continue updating your skill set. I knew I loved programming after writing my first Hello World program in high school. It’s amazing how fast you can go from nothing to a fully completed application. I love what programming/code can create.

Practice What You Care About

There are thousands of other software developers that are competing and applying to the same positions that you are. If you want to stand out, you must express your ability to learn while sharpening your skills and practice your skill set with a passion. If you are not passionate about what you are doing, you will not put in the effort to become a better developer. As I mentioned earlier, I graduated from a small college with no work experience. Due to this, I received many rejection letters from almost every company I applied. They would say, “You seem very smart, but we are looking for someone with a little more work experience.” This was annoying to hear. How could I get work experience if no one would give me a chance! After several months with no offers, I decided it was time to put down the video games and start showing that I cared. I started watching several tutorial videos on different topics:

  • .Net
  • MVC
  • AngularJs
  • SignalR

My brother was also trying to break into the computer science field and he was fiddling around with a gaming engine called Unity3D, which luckily used C#. My brother and I decided to develop an app for the iPhone. It took about a month to develop the app, but I learned a lot about the development life cycle and testing locally and in production.  Looking back now, these two areas were my weakest areas when interviewing for potential jobs since I had never dealt with the development process. With the app on the store and many hours of tutorial knowledge in my head, I went to two more job interviews. With this valuable experience, I was able to carry on discussions more naturally since I had more of an idea what I was talking about. I feel the companies, which interviewed me now, were able to see that I was a passionate worker. From those two interviews, I was offered three different jobs.

Getting a job that you are going to enjoy is very important. Make sure that you show the employers/interviewers this passion and love with projects and applications that you have developed and are continuing to improve. This article does not apply to just software developers, but anyone pursuing their passion. If you enjoy it, have passion and take the time to become the best at it. If you do this, you will get the job that you want!

When I was a little kid, I would occasionally get hiccups that rocked my diaphragm so badly my shoulders ached.  Grandma called during one of these uncomfortable bouts. I answered the phone with an embarrassingly audible gasp. I heard her smile through the phone as she spoke with her soothing southern accent, “You know what will get rid of those? A tablespoon of sugar under the tongue will fix you right up.” Scooping straight from the sugar canister was a rebellious act and against the rules in our house, but with her encouragement I decided to risk it.  I tried the purported antidote and she was absolutely right.

How do you remedy uncertainty about whether or not you found a bug?   When I find a bug, I need to be really sure that I actually found an issue or potential problem so there is no doubt in the minds of the reader of the bug report.  I need to clearly, concisely, and convincingly communicate to the developer and product management teammates why I think there is a problem so they want to fix it right away!  One technique that I use to determine if I found a bug is an internalized list of test oracles described in Michael Bolton’s article, Testing without a Map [PDF].   I use this list, originally created by James Bach, to examine general consistency heuristics:

  • History – Is this version of the system consistent with prior versions?
  • Image – Is this consistent with an image our organization wants to project, with our brand, or with our reputation?
  • Comparable Products – Is the system consistent with systems that are in some way comparable? This includes products in the same product line, competitive products, services; or products not in the same category, but process the same data; or alternative processes or algorithms.
  • Claims – Is the system consistent with things important people say about it in writing (help documentation and marketing materials) or in conversation (hallway and coffee mess chatter).
  • Users’ Desires – Is the system consistent with ideas about what reasonable users want? 
  • Product – Are elements of the system (or product) consistent with comparable elements in the same system?
  • Purpose – Is the system consistent with explicit and implicit uses to which people might put it?
  • Statutes – Is the system consistent with laws or regulations relevant to the product or its use?

I use this list to help me figure out if there is a fly in the sugar bowl, so to speak. If I cannot relate the issue to one or more of these consistency heuristics, then I can put the issue to rest, and not waste anyone’s time.  On the flip side, I am usually very effective in getting bug changes made since I can explain why the bug matters using one or more of these oracles. As Bolton explains in Oracles [PDF], multiple oracle heuristics may apply and some of these may contradict one another:  A product owner’s decision on what to do about the problem can be influenced by which oracles are applied.  Since our role as testers is to provide credible information, we may choose to use different oracles to temper our test framing or bug advocacy.

Test findings can trigger the following emotions: fear, anxiety, excitement, joy or euphoria.  These same emotions can cause hiccups too. [Ref]. 🙂 Over time with practice, this list can serve as a useful tool to double-check your logic and grow your skills and confidence in the art and science of bug advocacy.

Further reading:
Michael Bolton’s extension of the HICCUPPS oracle list in his blog post,  FEW HICCUPPS.
For more info on how to report bugs, see Cem Kaner’s Bug Advocacy: How to Win Friends, and SToMP BUGs [PDF].

Guest: Lanessa Hunter – QA Architect

I am a QA Lead and DevOps Team member with AppRiver. In my spare time, I am also a test jumper, speaker, blogger, and founder of local area Testing Meetup group, Gulf Coast Testers. I am passionate about the evolving role of QA, scaling testing in organizations, and tester skill development.

Host: Chris Hendricks – Software Developer

I am a software developer by profession. It’s what I do. It’s where I sharpen my sword. It’s where I practice jujitsu, to become an Afro Samurai in the code.  I am a believer, thinker, innovator, mold and statistic breaker, husband and father. I don’t fit into your box…

References:

Books

International E-zines

Collaborative Web Learning

Web

Episode Highlights:

  • “Making the invisible, visible”
  • Shared Language
  • Scaling Testing
  • Context-Driven Tester Skill Development & Education
  • Heuristic Test Strategy Model: reminding testers of what to think about when they create tests

Domain Driven Design (DDD) is one of the concepts we practice here at AppRiver. We come from the Greg Young and Udi Dahan school of DDD, which incorporates some elegant patterns such as Command Query Responsibility Separation (CQRS), event sourcing and service buses. These concepts are challenging to implement effectively, but with discipline and a focus on continuous improvement, the benefits of performance, scalability and developer productivity can be achieved.

As our business domain evolves, we are constantly taking steps to improve the way we utilize DDD, CQRS, event sourcing, and distributed applications. Below are some of the insights we’ve gained along the way that will guarantee quality and productivity remain at a high level.

Understanding the Domain is Key

To maintain the integrity of a DDD application, the organization’s domain experts must be deeply involved in the development process. It is essential that developers interact regularly with the domain experts, who may be product owners, developers, or other staff within the organization.

Understanding the domain provides context around the challenges facing developers.  This context ensures developers make smart decisions throughout the development process. Developers should have the opportunity to work in all areas of the system to broaden their understanding of the domain. Departmental swaps and cross training exposes developers to the business and increases domain knowledge.

Arrange Code Reviews with the Developer Domain Experts

Code reviews are certainly valuable on a number of levels. In DDD, code reviews with developers, who are domain experts, ensures code doesn’t just work, but it fits logically within the business domain. This prevents the proliferation of ambiguous domain models and domain services and aggregates from having too many responsibilities.

Domain driven design that is combined with CQRS and event sourcing introduces many components and layers, which are small and well defined.  These components include command handlers, event handlers, denormalizers, and aggregates. Without a clear understanding of the responsibility of each component, it can be easy to add code to any one of those components to produce the desired outcome for a user. However, placing code in the wrong component can lead to gradual degradation of system integrity, such as having business logic in multiple places, blending read and write data models, and bypassing the facilities provided by the system to transfer data (i.e., command and event handlers). Code reviews with the architectural experts reduces workarounds and architectural misunderstandings.

Event Replays Must be Fast and Robust

In an event sourced application, event replays are necessary to update local read stores with new data fields or new projections of event data. Ensuring that replays run quickly and are fault tolerant will improve developer productivity and deployment speed.

We gained considerable speed improvements with our replays when we migrated our event store from SQL Server to MongoDB.  We also migrated one of our read stores to MongoDB and updated its denormalizer to use the Mongo C# driver instead of Entity Framework, which compounded the performance gains.

We also made small improvements to our replay tool, such that it was resilient to exceptions and applied snapshots effectively so that all of the system’s events didn’t have to be replayed each time.

Instead of using different replay utilities for each read store, use a single tool to run replays. This replay tool should be able to take in arguments to specify data sources, data targets and whether the entire read model should be recreated.

Add Centralized Logging

When an application becomes more distributed and asynchronous, it is important to have a centralized logging system. Developers should be able to trace the entire life cycle of a request, all the way from the user interaction until the last endpoint is reached, and back again. In a CQRS system that incorporates command and event handlers, the use of correlation ID’s is a simple, yet valuable technique for tracking commands and events as they travel throughout the system.

We recently settled on Graylog as our primary logging utility for all applications and services and have been quite happy with it.

Automate Environment Configuration

Developers must be able to develop in a production-ready environment.  This means that all of the necessary applications, services, infrastructure and logging should be tested and debugged in a environment similar to production. Without automated and consistent environments, troubleshooting and integrating new code will become slow.

Consistency throughout the environments is increasingly important when dealing with distributed, asynchronous, event sourced systems that are composed of many services. Being able to simulate a production environment speeds up troubleshooting and enhances the debugging experience. Environmental automation and consistency can be achieved by using virtual machines, Docker, or custom configuration scripts.

Identify when Eventual Consistency is good, and when it isn’t

An asynchronous, event-based, and/or CQRS system probably means that changes to the data are not immediately available. This can lead to confusion for the person who clicks a Save button and expects to see their changes immediately. When designing the user experience, determine which features should be eventually consistent, and which ones should not. For features that do not produce results immediately, help the user understand that their results are being processed and will be available in the near future. For features that should operate more like traditional transactions, consider making those operations asynchronous all the way through the lifecycle of the command. This can be done by settings flags on the command request that indicate whether asynchronous operation is required, and guarantees that a result is returned after a completed transaction. The important thing to remember is that one size doesn’t fit all. Design the user experience for each feature or page appropriately.

Think about the ‘Q’ in CQRS

Localized read stores are important in order to maintain application boundaries, architectural boundaries or optimize queries. However, due to the added complexity that comes with additional event handlers and denormalizers, the read stores may be consolidated. In a DDD system, you must ask the following:

  • Do multiple applications have similar domain models?
  • Can query performance be sustained despite more normalized data structures?
  • Do applications belong within the same architectural boundary?
  • Are the differences in the data models so subtle that the boundaries become blurred?

If so, these applications may be able to use the same read store. On the other hand, if queries become sub-optimal due to normalized data, separate read stores may be the solution.

Simplify the System Architecture

Distributed, asynchronous systems increase complexity. In our CQRS implementation, we found ways to simplify our application by removing localized read stores and denormalizers that were adding more overhead than value due to the adverse effects on productivity. After removing these databases and denormalizers, we removed a ton of code, including a handful of .NET projects. This decreased the time it took to run a build, reduced the number of components that got deployed, and ultimately reduced deployment time and the number of components that required troubleshooting.

When thinking about how to partition applications and services, ask how many services need to be touched to add or modify a feature? How many repos will a developer need to check out before adding a feature? The potential scalability and performance gains associated with fine-grained services may be offset by the decrease in team velocity due to built-in complexity. Find creative ways to compose and partition services without sacrificing the architecture or team.

Conclusion

Discovering how to incorporate DDD and the related patterns into an organization take time. We’re glad we stuck with it and look forward to finding more ways to improve.