Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Travis 19 posts 99 karma points
    Nov 07, 2022 @ 20:17
    Travis
    0

    Backoffice extension Angular UI doesn't update after fetch call

    Creating a simple back-office plugin that has a button on it, and calls an API. For now, I'm just having the API return the current date and I'm attempting to display said date in a variable.

    The problem is, when I click the button, nothing seemingly happens, though the console log does show a value coming back from the fetch. However, when I click the button again (or anywhere else on the open area of the screen) the front-end updates with the same value that was in the console.log.

    I've also noticed that when I simply mouseover the left-menu pane, the UI also updates as intended. Is there something I'm missing that I need for the UI to update after a fetch call like this?

    Here's a video showing the issue: https://www.loom.com/share/992a50b0a24d40d4983e7541b95d6a76

    Here's the code:

    Controller

    angular.module("umbraco").controller("ImportContentController", function ($scope) {
        var vm = this;
        $scope.Message1 = "";
        $scope.Message2 = "";
    
        $scope.testMe = function () {
            (async () => {
                const response = await fetch('/umbraco/backoffice/plugins/welcomedashboard/process');
                let responseText = await response.text();
                $scope.Message1 = responseText;
                console.log(responseText);
            })();
    
            $scope.Message2 = new Date();
        }
        });
    

    HTML View

    <div class="import-content">
        <h1>Content Importer</h1>  
    
        <hr />
    
        <div class="import-content" ng-controller="ImportContentController as vm">
            <button ng-click="testMe()" class="btn btn-primary">Test</button>
            <div>Message1: {{Message1}}</div>
            <div>Message2: {{Message2}}</div>
        </div>
    
    </div>
    
  • Travis 19 posts 99 karma points
    Nov 07, 2022 @ 20:23
    Travis
    0

    One more observation, this must have something to do with the fetch code because when I simply just set the $scope.Message1 to new Date() without fetching it from the API, it works fine.

    Furthermore, I've tested this without async/await and just using promises and the same incorrect behavior occurs:

    angular.module("umbraco").controller("ImportContentController", function ($scope) {
        var vm = this;
        $scope.Message1 = "";
        $scope.Message2 = "";
    
        $scope.testMe = function () {
            fetch('/umbraco/backoffice/plugins/welcomedashboard/process')
                .then((response) => response.text())
                .then((data) => $scope.Message1 = data);
        }
    });
    
  • Bo Jacobsen 610 posts 2409 karma points
    Nov 07, 2022 @ 20:32
    Bo Jacobsen
    0

    Hi Travis.

    Try this

    angular.module("umbraco").controller("ImportContentController", function ($scope, $http, umbRequestHelper) {
        var vm = this;
        $scope.Message1 = "";
        $scope.Message2 = "";
    
        $scope.testMe = function () {
            umbRequestHelper.resourcePromise(
                $http.get('/umbraco/backoffice/plugins/welcomedashboard/process'),
                'Failed to retrieve data'
            ).then(function (data) {
                $scope.Message1 = data;
            });
        }
    });
    
  • Travis 19 posts 99 karma points
    Nov 07, 2022 @ 20:37
    Travis
    0

    I will do that, thanks. Does fetch not work in an angular function like I had it?

  • Travis 19 posts 99 karma points
    Nov 07, 2022 @ 20:38
    Travis
    0

    That did the trick! Can you explain why the initial code I had didn't work?

  • Bo Jacobsen 610 posts 2409 karma points
    Nov 07, 2022 @ 21:09
    Bo Jacobsen
    0

    Hi Travis.

    I am not an angular js expert.

    But i think fetch would work, but you would need to import a polyfill for it to work with older browser versions like IE11 . However i think the async/await part do not work as expected in the angular js version, Umbraco use.

    Instead we inject the $http service, that is a wrapper for the HttpClient and is core in angular js.

    Then Umbraco got a service named umbRequestHelper, that service we can use to return a promise, so we dont need to handle the responseMessage.

  • Bo Jacobsen 610 posts 2409 karma points
    Nov 07, 2022 @ 21:15
    Bo Jacobsen
    0

    A little bonus info.

    You might want to consider using Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath instead of /umbraco in case you ever change the umbraco backoffice path.

    Like

    $http.get(Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + '/backoffice/plugins/welcomedashboard/process')
    

    Or simply just remove Umbraco and the slash, might also work

    $http.get('backoffice/plugins/welcomedashboard/process')
    
  • Travis 19 posts 99 karma points
    Nov 07, 2022 @ 22:26
    Travis
    0

    Thanks for the help, Bo!

    I'm hoping the umbRequestHelper allows for ajax file uploading since the whole point of my plugin is to upload a file :)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies