0

How should application wide data be managed in a Durandal app?

For example, after the user logs in, I need to persist the UserName and UserId.

What I have tried is creating a singleton viewModel, and then import it where it is needed.

define(['knockout'], function (ko) {
return {
    currentUser: ko.observable(),    
};
});

Is this the correct pattern to use with Durandal?

Greg Gum
  • 33,478
  • 39
  • 162
  • 233
  • Absolutely, why not? You don't event have to declare `currentUser` as observable, unless you want to subscribe to that. – Dziamid Apr 21 '15 at 11:37
  • OK, thanks very much. Just new to Durandal (former Caliburn.micro user) and want to make sure I am following the proper patterns. – Greg Gum Apr 21 '15 at 13:25

2 Answers2

1

Here is a working example of using events for authentication:

//app/auth.js
'use strict';

define(function (require) {
    var
        ko = require('knockout'),
        User = require('auth/model/user'),
        api = require('auth/api'),
        events = require('durandal/events'),

        guestUser = new User({id: null}),
        currentUser = ko.observable(guestUser),

        signedIn = ko.computed(function () {
            return ko.unwrap(currentUser().id) !== null;
        }),

        load = function () {
            return api.getUser().then(function (dto) {
                var user = User.mapper.fromDto(dto);
                currentUser(user);

                return user;
            });
        },

        signIn = function (username, password, remember) {
            var that = this;
            return api.signIn(username, password, remember)
                .then(function (data) {
                    var user = User.mapper.fromDto(data);
                    currentUser(user);

                    that.trigger('signin:success', user);

                    return user;
                }, function (reason) {
                    that.trigger('signin:failure', reason);

                    throw reason;
                });
        },

        signOut = function () {
            var that = this;
            currentUser(guestUser);

            return api.signOut().then(function () {
                that.trigger('signout:success');
            });
        };

    return {
        load: load,
        signIn: signIn,
        signedIn: signedIn,
        signOut: signOut,
        currentUser: currentUser
    }
});

//main.js

define(function (require) {
   var auth = require('auth'),
       events = require('durandal/events'); 

   events.includeIn(auth);
});


//mysecuremodule.js

define(function (require) {
   var auth = require('auth');

   auth.on('signin:success').then(function (user) {
     //hello signed in user!
    });
});
Dziamid
  • 11,225
  • 12
  • 69
  • 104
0

I found a better answer to this and that is using events that are built into Durandal. This worked well.

Greg Gum
  • 33,478
  • 39
  • 162
  • 233
  • Well, that may be a solution, but you still have to inject some object to be able to subscribe to its events. So, there's no real difference. – Dziamid Apr 25 '15 at 06:43
  • True! If you want to post your response as an answer, I will accept it. – Greg Gum Apr 25 '15 at 12:26