0

I am new to AngularJS and still relativly new to JS at all. I tried to implement an angularjs project with login informations, etc.

Now I call by http request an API and get an answer with the user and the users objects. When I open the site, the console.logs show an result of 0 users and user=undefined. But when I open the objects in the console window, they are filled. So that means, the results are not there at the opening of the page, but are loaded async. So far, so clear.

But I thought the bindings in AngularJS were bindings that update themselves as soon as the value changes. I looked around for a while and found as answer that I should use a factory, but I don't know how. Can someone point me in the right direction please?

HTML

<h1>Hi {{vm.user.firstname}}!</h1>
<p>You're logged in! Test{{testService.test}}!</p>
<h3>All registered users:</h3>
<ul>
    <li ng-repeat="user in vm.allUsers">
        {{user.username}} ({{user.firstname}} {{user.lastname}})
        - <a ng-click="vm.deleteUser(user.id)">Delete</a>
    </li>
</ul>

controller.js

angular
    .module('app')
    .controller('HomeController', HomeController);

HomeController.$inject = ['UserService', '$rootScope'];
function HomeController(UserService, $rootScope) {
    var vm = this;

    vm.user = null;
    vm.allUsers = [];
    vm.deleteUser = deleteUser;

    initController();

    function initController() {
        loadCurrentUser();
        loadAllUsers();
        log(vm);
    }

    function loadCurrentUser() {
        UserService.GetByUsername($rootScope.globals.currentUser.username).then(resolve => {
            vm.user = resolve.message;
        });
    }

    function loadAllUsers() {
        UserService.GetAll().then(resolve => {
            vm.allUsers = resolve.message;
        });
    }

    function deleteUser(id) {
        UserService.Delete(id).then(() => {
            loadAllUsers();
        });
    }
}

EDIT: I found the solution. It is not the asyncronicity that makes a problem here. It is simply the reading of the returned data.

vm.allUsers = resolve.message.recodsets;

That gives all Recordsets for going through with ng-repeat and to get the one logged in user it was:

vm.user = resolve.message.recodset[0];

That is a little bit embarrassing but this way it works.

Marcel Grüger
  • 885
  • 1
  • 9
  • 25
  • AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc. – georgeawg Jul 12 '19 at 20:19
  • The promises being returned by the `UserService` are likely ES6 promises or promises from a third-party. It is best that the factory or service convert them to AngularJS promises before returning them. – georgeawg Jul 12 '19 at 20:30
  • @georgeawg and how do i do that? That was my question from the beginning: How can I create a factory or the like so that this works? I tried it with the "duplicates", but those point me to $q (which is not defined and shall not be defined there like I read) and to $scope.$apply (which is already declared and throws an error when I try to declare it a second time). – Marcel Grüger Jul 12 '19 at 21:29
  • If `$q` is not defined it needs to be injected into the factory constructor. Read [AngularJS Developer Guide - Dependency Injection - Factory Methods](https://docs.angularjs.org/guide/di#factory-methods). – georgeawg Jul 12 '19 at 21:39
  • Ok, I found my answer. There was nothing wrong with the async and binding. There was simply an error on reading the data. I update the question to show the correct way. – Marcel Grüger Jul 14 '19 at 16:52

0 Answers0