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 606 posts 2404 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 606 posts 2404 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 606 posts 2404 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 :)

Please Sign in or register to post replies

Write your reply to:

Draft