Upgrading from azure sdk for nodejs from 0.6.x to 0.10.0

Published October 28, 2014 4:45 pm


Our (under development) backend service is a nodejs service and uses azure sdk for nodejs to use azure storage. I found breaking changes recently and put on hold upgrade to latest azure sdk. Last week, I have taken up the work to integrate with the api changes between 0.6.x to 0.10 of azure nodejs sdk.

Our usage is is primarily around azure storage and especially apis for azure table and blob storage. I came across following changes:

  1. azure module has been divided into smaller modules and it is the aggregator module. It is possible to take dependency on smaller modules like azure-storage. I have not yet done that. That is remove dependency from azure and only take dependency on azure-storage.
  2. Not related to azuresdk; npm has also changed somewhere in between and now, it does not print modules it is downloading on the console. I liked it to printing friendly http gets on the console rather than simple rotating pipe (|) without any other information. In my opinion, status reporting degraded for npm install command.
  3. Type information is added to entity properties in entity descriptor (ed) parameter across all APIs. This is a big change. I have to take care of this at lot of places in code. Details later.
  4. tableService.queryEntity has been renamed to tableService.retrieveEntity
  5. tableService.queryEntities parameters has changed. Two new parameters – tableName and continuationToken
  6. blobService.listContainers has been renamed to blobService.listContainersSegmented and takes additional continuationToken parameter
  7. blobService.getBlobUrl renamed to blobService.getUrl and last parameter has changed from accessPolicy to sasToken. It has to be obtained by invoking blobClient.generateSharedAccessSignature() method.
  8. TableQuery has to be instantiated and not used as singleton. It does not encapsulate table name and hence, table name has to be passed separately to tableService.queryEntities method. from() call needs to be removed from the call chain building the table query.
  9. tableQuery.whereKeys is removed.  .where has to be used with filter as ‘ParitionKey == ? and RowKey == ?’
  10. filter string can have ‘?string?’ or ‘int32’ etc. in place of ? to accommodate typed arguments.
  11. queryEntities will only return one set of results. continuation needs to be handled by client. Earlier it was handling it.
  12. blobService.setContainerAcl – parameters have changed. it takes signedIdentifiers array directly (instead of a property in options) and extra publicAccessLevel parameter.
  13. tableService.beginBatch/commitBatch has been replaced by new class TableBatch and tableService.executeBatch method.
  14. tableService.createTableIfNotExists returns statusCode 200 if table already exists

A good number of breaking changes to keep one busy for couple of days to upgrade. Some of the changes are minor. Some require time to grasp and then, make the change.

Earlier, all entity properties where direct property on the ed object and used java script types. Now, it has its own typing and all of them look like “object” to javascript. Each such object has two properties: _ is the value and $ is the type name. It provides azureStorage.TableUtilities.entityGenerator to generate such objects.

// insert/update entity
// entityGenerator helper can be used to build entity descriptor when inserting or updating an entity
var entGen = require('azure-storage').TableUtilities.entityGenerator;
var myEd = {
    property1: entGen.String('hi'),
    property2: entGen.Int32(2),
};
tableService.insertEntity('mytable', myEd, ...);

// querying entities
var myQuery = new TableQuery().select().where('PartitionKey == ?', pk);
// var myQuery = new TableQuery().select().where('PartitionKey == ?string?', pk);
tableService.queryEntities('mytable', myQuery, null /*continuation token*/, onqueryentities);
function onqueryentities(e, r, response)
{
    // result r:
    // earlier: array of entities
    // now: object. { entries: array, continuationToken: ..}
    var entity = r.entries[0];
    // access entity.property1
    // earlier: entity.property1
    // now: entity.property1._
    var p = entity.property1._;
}

Were you also using azure nodejs sdk older version? How was your upgrade?

Support readiness before putting the winjs app out for trial

Published April 15, 2014 1:08 pm

Before deploying the current app under development for trial, I was thinking about app support. We needed:

  1. ability to quickly get the error information from the user.
  2. ability to get unhandled exception detail in case App crashes.

Let’s talk about first. Across the app codebase, Util method handleError is used to display error to the user. This method used the standard Windows.UI.Popups.MessageDialog. The solution was to add a ‘copy’ command to the dialog – to enable user to copy error to clipboard. The code for this is quite straight forward by going through some pages in msdn.

function handleError(error)
{
    assert.instanceOf(error, Error);
    var message = getDisplayErrorMessage(error);
    var popups = Windows.UI.Popups;
    var dialog = new popups.MessageDialog(message);
    dialog.commands.append(new popups.UICommand('Copy', copyCommand));
    dialog.commands.append(new popups.UICommand('Close'));
    dialog.defaultCommandIndex = 1;
    return dialog.showAsync();

    function copyCommand(event)
    {
        copyToClipboard({ message: message, stack: error.stack });
    }

    function copyToClipboard(data)    
    {
        assert.isObject(data);
        var dt = Windows.ApplicationModel.DataTransfer;
        var dp = new dt.DataPackage();
        dp.requestedOperation = dt.DataPackageOperation.copy;
        dp.setText(JSON.stringify(data));
        dt.Clipboard.setContent(dp);
    }
}

getErrorDisplayMessage is implementation specific. In our case, it goes through all innerError and error contextual detail – to form a display message. For example: every error related to a backend service call includes requestId guid. This enables support to trace down the faulting service request.

Regards second thing: WinJS.Application.onerror or Windows.onerror provides the hook to get to the unhandled exception. First tried solution was to copy the unhandled exception to clipboard through this hook. What I found – the error is copied to the clipboard but clipboard is cleared after the app exits. Hence, this solution does not work.

After little bit of bing, I found a post – which mentioned that the apphost source logs an administrative event in windows event log when the app crashes. Quickest way to get exception details to clipboard is –

  1. win+x key,
  2. selection event viewer,
  3. go to custom views->administrative events,
  4. right click the event with source ‘apphost’,
  5. copy->copy details as text.

Steps are long but for the time being – they looked good enough. event has all the details including exception fields and stack. Other solution is to log details to disk and add feature in app to share/copy to clipboard the data about last app crash. This solution looked costly for now.

With this, the app is support ready. How do you handle errors in your app and ask user to share the error info with you?

Adding a placeholder page in WinJS App

Published March 13, 2014 11:14 am

If you are building a winjs app – you may hit the need for a placeholder page. What I mean by placeholder page? Examples: initial login page. Once user has logged in, it should not show up in the navigation history; that is user must not be able to navigate it using back button on the next page.

This leads to obvious question – how do I remove a page from navigation history or how do I navigate to a page without adding it to <code>WinJS.Navigation.history</code>.

I made a failed attempt by resetting <code>WinJS.Navigation.history.backStack</code> when the navigate promise completes for the next page. This does not work since next page is already rendered by then and next page back button is visible. Clicking on the back button there does not do anything. but it must not be visible.

Next – google pointed to solution here by Kraig. This one line of code is the solution and needs to be placed when navigating away from the initial placeholder page like login page.

    WinJS.Navigation.history.current.initialPlaceholder = true;
    WinJS.Navigation.navigate('/pages/home/home.html');

dispatchEvent method invocation fails with error ‘java script invalid object’

Published February 18, 2014 9:41 am

This was kind of obscure error in a WinJS application yesterday. The object is non-null, mixed with WinJS.UI.DOMEventMixin but still obj.dispatchEvent(...) fails with the error ‘java script invalid object’. After little bit of pondering, It turned out to be an issue with stubbing done by binding. This object was being set to dataSource property of a custom control. This property is an observable property of the control. The stubbing for making the property observable was causing the error.

The solution was to unwrap the object before invoking the method.

    var obj = WinJS.Binding.unwrap(obj);
    obj.dispatchEvent('myevent', { message: 'my message' });

Hymn World 0.3.1 release

Published February 15, 2014 11:42 am

StorePromo-414x180We just released an update for Hymn World. It adds new 13 hymns to the existing collection of hymns. It also fixes some bugs when network connection is slow or flaky. Also note that if the network is slow, it may take longer to load the lyrics; you will see the progress ring for a longer period; be patient.

Since the hymns are added by volunteer effort, it takes longer to process and add new hymns; thanks for your patience. We saw request for search by author name in a comment recently. We will keep it on cards if there are more such requests. thanks for your feedback.

Handling data download in windows store application

Published February 14, 2014 1:43 pm

We have one app that downloads data as user moves through pages. There were few observations as I went through fixing issues there.

General gyan about adding support for network in the app can be found here; it is worth a skim; not all may apply for every app.

In our app, I need to handle mainly these things:

  1. download failure error handling – if the network connection is not available, or the http client async api calls throws or return any error.
  2. async download task cancellation – when the user moves between pages in the app, download async task for the previous page need to be canceled.

Network connection not available

The app want to display a clean error message to the user – “Internet connection is not available.” after determining conclusively that internet access is not there. The code snippet below does the job.

 
    using Windows.Networking.Connectivity;
    private bool CheckInternetAccess()
    {
        ConnectionProfile profile =
            NetworkInformation.GetInternetConnectionProfile();

        var level = profile != null ? profile.GetNetworkConnectivityLevel() : NetworkConnectivityLevel.None;
        if (level >= NetworkConnectivityLevel.InternetAccess)
        {
            // We have Internet, all is golden
            return true;
        }

        return false;
    }

    bool isMessageBoxActive;
    using Windows.UI.Popups;
    public async Task ShowMessage(string message)
    {
        if (this.isMessageBoxActive)
            return;

        this.isMessageBoxActive = true;
        MessageDialog dialog = new MessageDialog(message);
        await dialog.ShowAsync();
        this.isMessageBoxActive = false;
    }

    bool internetOk = this.CheckInternetAccess();
    if (!internetOk)
        this.showMessage("Internet connection is not available");

This works for displaying one time error message to the user. Since in my case, there was no need to keep a check if the connectivity goes down/up, I have not used NetworkStatusChanged event.

HttpClient.GetAsync api error handling

Next the api call to download the data GetAsync need to be cancelable and it’s exception & errors need to be handled. To cancel,  api overload taking a cancellationToken can be used. CancellationTokenSource (cts) provides the cancellation token which can be passed to the api. To cancel the task, cts.Cancel() needs to be called. To understand – How to cancel async task – this msdn topic will help.

The code below handles exception and errors.

    public async Task LoadData(CancellationToken cancellationToken)
    {
        if (this.data != null)
            return;

        bool internetOk = this.CheckInternetAccess();
        if (!internetOk)
        {
            var message = Singletons.ResourceLoader.GetString("InternetNotAvailable");
            throw new DataLoadException(message);
        }

        HttpClient client = new HttpClient();
        using (client)
        {
            HttpResponseMessage response = null;
            try
            {
                response = await client.GetAsync(this.dataUrl, cancellationToken);
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                var m = Singletons.ResourceLoader.GetString("DataDownloadException");
                var fm = string.Format(m, this.Title, e.Message);
                throw new DataLoadException(fm);
            }

            if (!response.IsSuccessStatusCode)
            {
                var message = Singletons.ResourceLoader.GetString("DataDownloadFailed");
                var formattedMessage = string.Format(message, this.Title, (int)response.StatusCode);
                throw new DataLoadException(formattedMessage);
            }

            try
            {
                var content = await response.Content.ReadAsStringAsync();
                this.data = DataParser.Parse(content);
            }
            catch (Exception)
            {
                var m = Singletons.ResourceLoader.GetString("DataParsingFailed");
                var fm = string.Format(m, this.Title);
                throw new DataLoadException(fm);
            }
        }
    }

The calling code provides the cancellation token and calls cancel during code paths where the async task needs to be canceled.

    private CancellationTokenSource dataLoadOperationCts;
    private void Unload_handler()
    {
        if (this.dataLoadOperationCts != null)
        {
            this.dataLoadOperationCts.Cancel();
            this.dataLoadOperationCts = null;
        }
    }

    private async void initialize()
    {
        this.dataLoadOperationCts = new CancellationTokenSource();

        // need to trigger download of data. 
        ...
        Exception error = null;
        try
        {
            await item.LoadData(this.dataLoadOperationCts.Token);
        }
        catch (DataLoadException err)
        {
            error = err;
        }
        catch (TaskCanceledException)
        {
            // do nothing
        }

        if (error != null)
            await this.ShowMessage(error.Message);
    }

The LoadData helper method raises DataLoadException with app friendly error message which are then caught and handled by the UI code. DataLoadException and Singletons class are not included in the code listing but they are kind of obvious.

Few more things:

  1. Unit testing was important here. There are code paths that can not be reached easily. I have to exercise the code path by throwing exception by hand in code or using slow network where download took time & canceling midway when the GetAsync call did not yet complete or disconnecting the network. For slow network, I have used the slow 2g mobile internet by sharing it using “internet sharing” feature on mobile.
  2. Using Xxxasync methods on http client is key. Don’t try to read the stream returned using GetStreamAsync and then use sync methods like TextReader.ReadToEnd. That will result in sync read and responsiveness issues in app.
  3. Need to handle all exception thrown by async api or unhandled exception will cause app to crash.
  4. I did a brief search for System.Net.WebClient vs System.Net.Http.HttpClient after finishing the work. It looked like HttpClient is newer api entry.

Every app has different set of network access needs. HTH. Share your learnings through comments.

Taking an IC role after being in programmer lead role

Published February 4, 2014 3:10 pm

In the last post, we talked about taking a programmer lead role. Once you are in a programmer lead role for couple of years, you may feel the urge to go back to your roots; that is taking IC (individual contributor) role. The reasons can vary:

  1. Lost touch of code because of not coding enough in lead role.
  2. Need to update on new frameworks/concepts since software development goes through paradigm shift 1-2 times in a decade typically.
  3. Need to upgrade my design/architectural/coding skills to next level.
  4. Find the lead role stressful to be responsible for something that you don’t do yourself.
  5. lead role feels like glorified cleric job to divide work and manage delivery.
  6. work-life balance is disrupted. I come the first and leave the last. Work never seems to end.
  7. Writing and delivering people reviews is stressful.
  8. Feel like sandwiched between management and team.
  9. Team health metrics for you are not favoring you in lead role.
  10. For personal reasons, you can’t take up more responsible role for a period.

As far as I can think, reasons typically fall around this. They can be categorized into the following:

  1. Need to upgrade technical skills
  2. Need skills to cope up with lead role
  3. others

For (1) and (2) – there is choice to stay with lead role or go to IC role. For (3) – it is like you have to simply go back to IC role; there is not a choice as such. For example, I have family emergency for a year and need to scope down on work responsibilities. In such case, you and your manager need to work out if there can be different role for you interim. Typically a lead role does not fit part time.

Need to upgrade technical skills

This might be quite stressful if you think your tech skills are rusting and you are struggling to find time to tune them in your role. Lead role has multi-tasking as given and high chance of getting randomized at least in the beginning. Finding your uninterrupted few hours to up your tech skills is a struggle at times. Soon you are getting concerned about it if not losing sleep over it. A techno-manager discipline focused role (dev/test) requires one to be up to date in his tech skills to be respected and deliver business.

There can be many solution for this. Prevention is the best approach. In this approach, you step into lead role – as we talked in the last post – only when you consider yourself ace developer. That means to start with, you have ace tech skills. If not, this approach won’t work for you. Now that you have a good tech skills to start with and say beginner managerial skills, focus hard on your team skills like setting team member goals, negotiation, impact and influence, mentoring and career development, giving feedback, leadership, writing and delivering people performance reviews. code and design reviews – to impart your good practices to team members and add your contribution to project technical deliverables. Each of these skills require their own post to go into detail but we will talk that another day.  First 1-2 years is key when making a transition to lead role – to ace these skills and to graduate out of beginner manager. Feeling uncomfortable at the beginning is being human. but sign of graduation is that you start feeling comfortable with these. e.g. you manage a feedback session as you would write code.

It is good to make time to write code themselves. Start with 3 team members and add slowly. As you get comfortable with managing, you find more time and use it to write code (that implicitly means you get to design also). This does not mean you will not get outdated. but it will take longer and reason to update yourself will be little different in this scenario.

As you move from beginner developer to advanced developer  on IC track, you get to solve more involved technical problems that requires 100%+ focus from a person. As a lead, it is hard to take up such assignments on your plate without stretching++ yourself. For example – taking up performance tuning for a component, security review of the project, prototyping to boot strap a new project. In such cases, it is wise to switch to advanced developer (IC role) for a period. After such project, you are a better lead. People skills don’t rust easily and stay with you longer.

Doing back and forth between IC, lead and M2 role in a discipline is healthy. It builds perspective and keeps you grounded. It requires commitment, hard work, patience and little bit of courage.

Need skills to cope up with lead role

In IC role, you used to do things. In lead role, your b**t is on line for team deliverable and requires you to get things done. It comes with additional ambiguity. First of all, it will need us to be comfortable with higher ambiguity in the system. For example: now it is not only about this-code-does-not-work but about work does not fit schedule, unplanned leave in team etc. Need to plan the work; stretching to meet target won’t work without planning first. After the planning, accept the ambiguity, and deal with it when it comes. Know what you can get done, have some level of buffer, under commit and over deliver vs over commit and under deliver.  Beyond that – Analysis paralysis or scheduling the unknowns won’t work. Basic principles like manage long poles in schedule, load balance, creating backup for team members, schedule risks first so that you have time to react, schedule prototype to iron out technical unknowns before committing to schedule if there is lot of unknowns, prioritize, cut features or buy more time, will help.

Communication is key to team work and deliverables. This is key to pass the right expectation to team. If you have steep target and soft in communicating the urgency – you will feel being sandwiched between the team and your management. It is like management want urgent deliverables and team is conducting business as usual.

Delegation at right level is key. e.g. You can’t delegate division of work and resolving dependencies to your developers. then, you don’t know how deliverables will line up to target date. At the same time – you can’t keep the work of team members with you. You can’t clone yourself and hence, you can only end up doing mornings and late evenings for the unscheduled work – to meet team deadlines. Again, this topic requires much more than one para. but you get the point right?

Change is always hard. Don’t look it through a wrong lenses in the beginning. This will lead to thinking that your work does not help add any value. You are simply a glorified cleric dividing the work among team members. You value addition is through code and design reviews. Further, you can generate able trained developers for the organization. An able dev lead is a factory that generates ace developers. Needless to say – don’t stop coding yourself.

Writing people reviews may come as shocker for some at the beginning. Be objective. Focus on the behavior, results rather than individual. Doing frequent feedback will help not have one marathon annual review. Write detailed feedback. Do one review a day. Keep 1-2 weeks of schedule around annual review to be able to reflect and do good home work before delivering the review.

Personal connection with team is key have good team health. It’s like making time to laugh together by going for a lunch or dinner on an occasion. Across the table, you talk anything from cricket, movies, music to physics. You get to connect as team. You open up to each other to discuss things. Every individual is a human apart from developer. A manager role is to marry business to people. You need to know their aspiration, and constraints; guide, and mentor them. One need to see how work is adding to his skills and growth apart from delivering business. These are basics of team health. Again – this requires much more discussion than one para. Nevertheless, one need to be little more than a nerd – a little social being to build team health.

In summary, moving between IC, lead and M2 (second level manager) roles is healthy to build perspective and good to consider doing this. Lead/manager role requires honing people/team skills which needs attention and action when taking the role first time. Good luck to you to be an ace IC, lead and M2 . Keep rocking! Next time – we talk about whether to take a programmer role for life time career?

 

To take or not to take a programmer lead or manager role

Published December 4, 2013 1:02 pm

In the last post, I tried to go over natural traits of a programmer and see whether one has natural inclination to be a programmer? As a programmer, you come at a crossroad – typically in 1-5 years – where you have to decide whether you want to lead a team? It exposes itself as an opportunity or you come across it when thinking about your career growth. In my case, it came as an opportunity within 3rd year of the career as programmer.

It is human to feel uncomfortable with the change at the onset. I did not know much theory about change mgmt. then. Later, I had come across theory about how people respond to change. Closest picture I could find on net about that is here and here. Your response to the expected change might be inline with the curve in the picture. That is ok but there is more to this.

There are 3 parties involved when you take up lead role – you, work and team. As long as you work as a programmer (individual contributor aka IC), there are only two parties involved – you and work. This change is key to note. There was so much to learn when I boarded my first job. My key focus at that time was to grasp, learn at exponential rate. In a way, focus is so much on you and what you produce; your excellence. The other parameter – team – brings team deliverables, team performance and career mgmt. to name a few items. Like it or not – they are equally important if not more – in your role as lead. (There are many titles that are used for this – like dev lead, project manager, test lead, qa lead. I will keep it as lead in the post.). It is good to come to terms with this. This will impact how much time (at the least in the short term) you can spend programming/researching yourself. Typically, you get to spend good 50% time or more with other items – to begin with.

Lead role typically comes with career growth though it may not always be the case. There are companies where there is a parallel career path for IC and manager. That is there is no need to be a lead – only for growth. Also in this role, supporting people through their career growth generates intangible job satisfaction. It is very key to know your intention. That is whether you are interested in the lead role for career growth or supporting people or both. If for career growth only or mostly, it may not work well. It will be hard to grow as a manager without being genuinely interested in people, and you may finding it taxing. Well, we all see during our career – good managers and bad managers. How come the bad manager could grow so much in that case? You are right. Let me put it other way – you might not make a great manager although you could still grow based on other parameters like – taking scaled up responsibility and deliverables. In nutshell, it will always help – to have genuine interest in the growth of the people – as manager. It may not stop you from taking a manager role.

First level manager are better accepted as techno managers. Are you at a stage where you have something to impart to the fellow team members? Some of these questions might help know that objectively?

  1. Do you ace your deliverables in the project?
  2. Are you considered a go to person for some of the component(s) in the project?
  3. Have you successfully on-boarded/mentored new joiners in the project?
  4. Do you produce code as per the standards of the group – if not help improve it?
  5. Do you debug difficult technical bugs and issues for the project?
  6. Have you handled external communications (technical or otherwise) sometimes?
  7. Have you negotiated your schedule/deliverables with your manager?
  8. Have you debated technical designs/issues with fellow team members?

Some of these question will help answer objectively whether your team can look up to you – to learn & lead and whether you have basic skills to lead a team. I am not going through the laundry list of skills here to avoid going by the book. Your organization might have listed the management skills formally and it won’t harm to skim through them.

If these parameters are aligned – that is 1) you are ok juggling – you, work and team – priorities and its impact on your daily working pattern 2) you are interested in people n their career 3) you ace your art as IC and have basic skills required to be first level manager, it won’t harm to take your first plunge into leading a group of programmers. Even if you are not be able to make an long term choice – to take IC vs lead track now, experiences from lead role will help hone up new skills that compliment technical skills for your career growth. For example: it helps – to be a better communicator, to be able to influence fellow team members, have empathy and to be little more team-social – as IC.

If you have made a choice to take up lead role, congratulations in your new role and best wishes! After few more years into your lead role, you may face more choices. For example: shall I go back to an IC role, is moving between IC and lead roles ok, Shall I take up M2 role, Can I take up programmer role as life time career path? Let’s pick up one of these in the next post.

Using WinJS.Binding.List to update the list view

Published December 3, 2013 1:06 pm

WinJS.UI.ListView is the most used control in WinJS library. At the beginning, you typically start with static List views. In such List Views, data does not change after it is bound. You may have to sort or group data which can be achieved using createSorted or createGrouped methods on List. You can order the items, group the items, and order the groups using these methods. If you follow some of the msdn listview samples, it is sort of clear. (Note: not all samples needs to be followed to get hang of list view. Some of them like custom data source, incremental loading are advanced scenarios).

When you working with dynamic data, list view updates as user interacts with the list view. Examples:

  1. User can right click a item, and delete it using contextual app bar command.
  2. User clicks/taps an item. The item is either removed or updated.

List view elements sort order and grouping needs to be maintained after the item change or list changes. In this post, let’s look into (2). I will try to cover (1) in another post. To go over this, let’s take a simple problem of displaying list of todo tasks.

  1. The tasks should be displayed in two  groups – ‘todo’ and ‘done’ groups.
  2. When a task is clicked or tapped in the todo group – it is moved to ‘done’ group.
  3. ‘done’ group should maintain only the latest 5 done tasks. oldest task gets off the list when list grows beyond 5 tasks.

my-tasks-1With this, Let’s look at the HTML

<div id="todoListView" data-win-control="WinJS.UI.ListView"
    data-win-bind="winControl.itemDataSource: items.dataSource; winControl.groupDataSource: items.groups.dataSource"
    data-win-options="{
      itemTemplate: select('#todoItemTemplate'),
      groupHeaderTemplate: select('#groupHeaderTemplate'),
      selectionMode: 'none', swipeBehavior: 'none', tapBehavior: 'invokeOnly' }">
</div>
  1. list should have tapBehavior set to invokeOnly to enable click/tap.
  2. itemTemplate and groupHeaderTemplate are set which is kind of obvious.
  3. this snippet binds itemDataSource and groupDataSource in html. If you don’t have view model (MVVM) separate in your code, you may set it in the .js file.

Let’s look at the sample data.

var data = [
    { status: 'todo', title: 'wake up' },
    { status: 'todo', title: 'brush your teeth' },
    { status: 'todo', title: 'take bath' },
    { status: 'todo', title: 'do yoga' },
    { status: 'todo', title: 'take breakfast' },
    { status: 'todo', title: 'check email' },
    { status: 'todo', title: 'check facebook' },
    { status: 'todo', title: 'check stackoverflow forum' },
];

We will sort the list using the sort key <status, finishTime>. finishTime will be added whenever user taps the item. todo status is sorted before done status. finishTime is sorted in descending order. This way – all done items are order towards end of the list. Further, If any item is to be dropped, it is at the end of the list.

 

    function compareStatus(t1, t2)
    {
        if (t1 == t2)
            return 0;
        else if (t1 == 'todo')
            return -1;
        else
            return 1;
    }

    function compareFinishTime(d1, d2)
    {
        if (d1 == undefined && d2 == undefined)
            return 0;
        // treat unfinished task ahead in sort order
        else if (d1 == undefined)
            return -1;
        else if (d2 == undefined)
            return 1;
        else
        {
            var t1 = d1.getTime(), t2 = d2.getTime();
            // treat recently finished task ahead in sort order
            if (t1 > t2)
                return -1;
            else
                return 1;
        }
    }

    var sortedList = list.createSorted(function compare(i1, i2)
    {
        var c1 = compareStatus(i1.status, i2.status);
        if (c1 != 0)
            return c1;
        var c2 = compareFinishTime(i1.finishTime, i2.finishTime);
        return c2;
    });

Further, we use createGrouped to group the sorted items and order the groups.

    this.items = sortedList.createGrouped(function groupKey(item)
    {
        return item.status;
    },
    function groupData(item)
    {
        return { title: item.status };
    }, 
    function groupSorter(g1, g2)
    {
        // keep todo items group b4 'done' items group
        if (g1 == g2)
            return 0;
        else if (g1 == 'todo')
            return -1;
        else 
            return 1;
    });

Now, to move the item from ‘todo’ group to ‘done’ group – we can change the item in the iteminvoked handler and notify the list for item mutation using notifyMutated method. Once notified, list sorted and grouped projection will update themselves. It will reflect in the bound list view.

 
registerItemInvokedHandler: function registerItemInvokedHandler()
{
    function oniteminvoked(event)
    {
        var index = event.detail.itemIndex;
        var item = this.viewModel.items.getAt(index);
        // click on 'done' tasks should be noop. 
        if (item.status == 'done')
            return;
        item.status = 'done';
        item.finishTime = new Date();
        this.viewModel.items.notifyMutated(index);
        // schedule removal for later using setImmediate
        WinJS.Promise.timeout().then(removeIfReqd.bind(this));
    }

    function removeIfReqd()
    {
        var count = 0;
        var items = this.viewModel.items;
        for (var i = items.length; i > 0; i--)
        {
            var item = items.getAt(i - 1);
            if (item.status == 'todo')
                break;
            count++;
        }

        // remove only if more than 5 'done' items
        if (count > 5)
            items.splice(items.length - 1, 1);
    }

    todoListView.addEventListener('iteminvoked', oniteminvoked.bind(this));
},

my-tasks-3* Note the code above references items from the viewModel. That needs to be modified to reference items as per your code.

This way – we saw in this post – how createSorted, createGrouped along with notifyMutated – can be used to build a dynamic list view.

To be or not to be a programmer?

Published December 2, 2013 3:44 pm

Do you have appetite to be a programmer? Do you relish programming? Can programming be a life time career for you? These might be some of the questions –  a programmer may ask himself at different stages in his career. There is no definitive formula – I have seen – to get a yes/no answer. I am also somewhere in the mix, and can share some of my experience.

When I was graduating from the college in comp sc., I got first introduction to programming. As part of the first semester to learn Pascal, I got the first kick for the programming, and found like minded classmates; among us we gave competition and positive pressure to keep leaping and stay one semester ahead. We were always one semester ahead for the programming courses. That time – I did not ask myself – whether I have appetite for programming or whether I relish programming – but I simply found my appetite for it and relished it. Looking back, I can see few things that stand out if one has appetite for programming:

  1. Getting the output after few-hours of hard work – putting the code – gives immense satisfaction.
  2. You are impatient to put all details on paper or a document. You itch to code it and see it working. You would draw/put a rough sketch/skeleton pseudo code and then, get to code. Iteratively – add functionality and see it working.
  3. You have more inclination to mathematical problems than theoretical subjects like History. Because you find it intuitive to score well in logical subjects. Once the concept is learnt, that is it; no mugging required.
  4. You itch to learn new languages. but time constraints keep you away if at all. You definitively take up assignments outside the course – out of your interest.
  5. You wish if you knew all apis by heart – that way you can code fast. You learn the shortcuts of the code editors. You learn typing if you don’t know already;)
  6. You care for good design but you are averse to any process overheads that let you not produce code. You certainly don’t gel well with process-first managers.
  7. You take bugs in code personally and constantly challenge yourself to produce bug free code. I have heard Sachin saying once that he thinks over after each match – the reason he got out. You would think every time you fix a bug – what would have saved that bug.
  8. Code is your art. You strive to get better at it. You are naturally inclined to pick good treats from well written code. You hate badly written code and want to eliminate it. You always carry your code with you on your external disk, pen drive, cd etc. unless the IP rights prohibit you.
  9. You strive to get working code daily if not every hour. You can sit at stretch for 4-10hrs daily coding.
  10. You rewrite your own code until it matches your criterion of quality.
  11. You like being in code than in ppts.

If you see some of these traits, it is likely you have natural flair for being a programmer. It is very likely that you have already embarked on it since it kind of comes natural. The real questions start popping years later when 1) one is faced first time with the choice of taking up lead/manager role and later, when 2) he/she needs to decide whether this can be a career choice for life time. (1) is easier than (2). Let’s catch up on this in the next post.