身份验证:"cannot execute _executeQueryCore until metadataStore is populated"

Authentication: "cannot execute _executeQueryCore until metadataStore is populated"

我正在尝试向我的移动应用程序添加身份验证,该应用程序是使用 Angular 和 Breeze 构建的。

在我的 app.js:

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push(intercept)
});

//intercept runs on every http request and response
//When there is a 401 error it uses broadcast to send an event to 
//the application scope
function intercept($rootScope) {
    return {
        request: function (config) {
            $rootScope.$broadcast('loading:show');
            return config;
        },
        response: function (response) {
            $rootScope.$broadcast('loading:hide');
            return response;
        },
        responseError: function (error) {
            if (error.status === 401) {
                $rootScope.$broadcast('error:401');
            }
            return error;
        }
    }
}

app.run(function ($rootScope, $ionicLoading, $state) {
    $rootScope.$on('loading:show', function () {
        $ionicLoading.show({ template: 'Loading...' });
    });

    $rootScope.$on('loading:hide', function () {
        $ionicLoading.hide();
    });

    //401 errors mean the user is not authenticated
    //display a login dialog
    $rootScope.$on('error:401', function () {
        $ionicModal
            .fromTemplateUrl("app/user/login.html", { focusFirstInput: true })
            .then(function (modal) {
                modal.show();
            });
    });
});

在我的 dataContext.js 中:

var properties = [];

function getProperties(refresh) {

    if (!refresh && properties.length > 0) {
        return common.$q.when(properties);
    }

    var query = EntityQuery
                .from('Properties')
                .select('ID, NameNumber, StreetName, ...etc')
                .orderBy('StreetName, NameNumber')
                .toType("Property")
                .using(manager)
                .execute()
                .then(querySucceeded, queryFailed);

    return query;

    function querySucceeded(data) {
        //set the properties held in memory
        properties = map(data.results);
        return properties;
    }

    function queryFailed(error) {
        console.log("Error while making http call: " + error.message);
        //return the properties held in memory
        return properties;
    }
}

逻辑是这样的:

  1. getProperties() 调用

  2. EntityQuery 触发对 http://.../breeze/breeze/Metadata"

  3. 的请求
  4. 响应为 401(用户未通过身份验证)- 正如预期的那样

  5. 'error:401' 事件被广播和处理并显示登录屏幕

这一切都很好。

现在,如果我取消登录对话框,然后刷新,将再次触发 getProperties,但这次我在 queryFailed 函数中收到此错误报告:

cannot execute _executeQueryCore until metadataStore is populated

所以我猜 Breeze 知道之前有一个呼叫,因此希望它在那里,即使它因 401 而失败。我能做些什么来解决这个问题?

在尝试了许多其他事情之后,我终于意识到我需要通过拒绝来解决 responseError。否则(我猜)Breeze 认为 MetaData 调用成功,随后尝试访问它,然后在不成功时生成错误:

responseError: function (error) {
    if (error.status === 401) {
        $rootScope.$broadcast('error:401');
    }

    //return error; wrong!

    return $q.reject(error);
}