View setup in progress

I'm interested in implementing something along these lines:

app.config(function($routeProvider){
$routeProvider.when('products/list', {
    controller: 'ProductListCtrl',
    templateUrl : 'products/list/view.html',
    resolve : { data : function(){
        ...
    },
    loadingTemplateUrl : 'general/loader.html'
}
});

My goal is to have the loading page displayed in a separate view.

This approach would result in cleaner code in both the view and controller of each page, eliminating the need for <...ng-include ng-show="loading"...>. It would also eliminate the need for $scope.$watch to monitor data changes. I'm curious if there is a tidy solution to accomplish something similar (not necessarily within the .config method), or if there is an alternative library that could assist with this?

Answer №1

If you're looking to display a general template for all state transitions while the data is being resolved, my recommendation is to listen for the events triggered by the routing library. This way, you can manage all state transitions from a single central point without cluttering the routing configuration, which could prove to be quite challenging.

For more information, you can refer to the documentation for $routeChangeStart, $routeChangeSuccess, and $routeChangeError on the Angular router documentation.

Answer №2

Recently, I undertook the task of creating a new service along with a new view directive. Surprisingly, the process turned out to be much simpler than I initially anticipated. The newly developed service allows for a clean separation between the main view and the loading view, which can now be reused across all pages of the application. In addition, I incorporated the option to configure an error template URL and error controller for instances when the loading process fails.

The Angular $injector, $templateRequest, and $controller services played a crucial role in carrying out most of the necessary operations. My role involved connecting a directive that relies on these services to the appropriate event ($locationChangeSuccess) and to the promise obtained from the resolve object's functions (using $q.all). This connection was established within the route service, where the service selects the correct template URL and controller to be passed on to the directive for handling.

Here's a condensed version (excluding the getCurrentConfig method):

RouteService:

(function () {
    'use strict';

// provider: 

    angular.module('pikcachu')
        .provider('pikaRouteService', [function () {

        var routeConfigArray;
        var otherwiseRouteConfig;
        //configuration methods
        this.when = function (url, routeConfig){
            routeConfigArray.push({url: url, routeConfig: routeConfig});
            return this; 
        }
        this.otherwise = function(routeConfig){
            otherwiseRouteConfig = routeConfig;
            return this;
        }
        // service factory:
        this.$get = ['$rootScope', '$location', '$q', '$injector', '$templateRequest', 
            function ($rootScope, $location, $q, $injector, $templateRequest) {
                function RouteService() {
                    this.setViewDirectiveUpdateFn = function(){ /*...*/ }

                    function init(){
                        $rootScope.$on('$locationChangeSuccess', onLocationChangeSuccess);
                    }

                    function onLocationChangeSuccess(){
                        // get the configuration based on the current url
                        // getCurrentConfig is a long function, because it involves parsing the templateUrl string parameters, so it's left out for brevity
                        var currentConfig = getCurrentConfig($location.url());
                        if(currentConfig.resolve !== undefined){
                            // update view directive to display loading view
                            viewDirectiveUpdateFn(currentConfig.loadingTemplateUrl, currentConfig.loadingController);
                            // resolve
                            var promises = [];
                            var resolveKeys = [];
                            for(var resolveKey in currentConfig.resolve){
                               resolveKeys.push(resolveKey);
                               promises.push($injector.invoke(resolve[resolveKey]));
                            }
                            $q.all(promises).then(resolveSuccess, resolveError);
                            function resolveSucces(resolutionArray){
                               // put resolve results in an object
                               var resolutionObject = {};
                               for(var i = 0; i< promises.length;++i){
                                  resolved[resolveKeys[i]] = resolutionArray[i];
                               }
                                 viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
                            }
                            function resolveError(){
                                viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
                            }
                        }
                    }

                    init();
                }
                return new RouteService();
            }]
    })();

View directive

(function () {
    'use strict';
    angular.module('pikachu')
        .directive('pikaView', ['$templateRequest', '$compile', '$controller', 'pikaRouteService', function ($templateRequest, $compile, $controller, pikaRouteService) {

            return function (scope, jQdirective, attrs) {
                var viewScope;

                function init() {
                    pikaRouteService.listen(updateView);
                }

                function updateView(templateUrl, controllerName, resolved) {
                    if(viewScope!== undefined){
                        viewScope.$destroy();
                    }
                    viewScope = scope.$new();
                    viewScope.resolved = resolved;
                    var controller = $controller(controllerName, { $scope: viewScope });
                    $templateRequest(templateUrl).then(onTemplateLoaded);
                    function onTemplateLoaded(template, newScope) {
                        jQdirective.empty();
                        var compiledTemplate = $compile(template)(newScope);
                        jQdirective.append(compiledTemplate);
                    }
                }

                init();
            };
        }
    ]);
})();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is Angular's Http Module classified as middleware?

As I delve into the world of middleware, I've encountered a bit of a challenge trying to fully grasp its concept. Currently, I'm exploring the ExpressJS documentation and its explanation of a middleware function: "Middleware functions are functi ...

Having trouble retrieving a variable from my AngularJS service within my controller

I am trying to gather information about the user currently logged in. I have stored the data in a variable called currentUser, but I am encountering issues when trying to access it from my controller. Here is the code snippet from authentication.service.j ...

Validation in Ajax Response

When receiving an object from my API call, I want to perform error checking before displaying the JSON data in my view. function response(oResponse) { if (oResponse && oResponse != null && typeof oResponse === "object" && oResponse.response ...

Razzle fails to initiate the server

After creating my React project with Razzle.js and downloading it from a repository, I encountered an issue when trying to run it. Upon running yarn start, the screen gets stuck at a message saying the source is compiled and server is running on localhost: ...

The communication between the Next.js and Node.js servers is being obstructed as the request body fails

Could you lend me a hand with this issue? Here is the function being called: function apiCreate(url, product) { console.log('Posting request API...' + JSON.stringify(product) ); fetch(url, { dataType: 'json', method: 'post ...

invoke the modal function from a separate React file

I am currently studying react and nextjs. I am experimenting with calling a modal from another file but unfortunately it's not functioning as expected. Here is the code I used: Signin.js import { Modal } from "react-bootstrap"; import { u ...

Using AngularJS to filter search results based on two user-provided input parameters

Currently, I am working on an Angular application that presents movies in a table format with search input and dropdown filter by genres. As I work on this project, my main focus is finding a way to filter search results based on both the text entered in t ...

How can I use jQuery to create a new div element if it is not already present

I am familiar with how to add a class if it does not already exist, for example: $("ul:not([class~='bbox'])").addClass("bbox"); Alternatively, if(!$("ul").hasClass("class-name")){ $("ul").addClass("bbox"); } However, I am unsure how to c ...

Is there a way to mount or unmount a React component by pressing a single key?

I am currently developing an application that showcases 3D objects upon pressing certain keys on the keyboard. My goal is to have these objects disappear after 2-3 seconds or once the animation completes. Below is the component responsible for managing th ...

Is there an easy method for customizing scrollbars?

I'm looking to include an "overflow:scroll" in a navigation div, but the default scrollbar on windows is unattractive. Is there a simple way to customize the scrollbar without having to download extra JavaScript libraries, APIs, and so on? ...

Finding and removing the last portion of the innerHTML can be achieved by employing specific techniques

Looking to manipulate a <div> element that includes both HTML elements and text? You're in luck. I need to locate and remove either the last, nth-from-last, or nth plain text section within it. For example: <div id="foo"> < ...

Updating Loader on Button Press in Bootstrap 4.4: Switching or Concealing Spinner Post-Loading

After searching through various questions related to this topic, I have yet to find one that specifically tackles what I'm looking for with the latest Bootstrap version 4.4. Before we go any further, please take a look at this fiddle: https://jsfiddl ...

AJAX call error: Invocation not permitted

I'm currently working on a web application using JQuery that requires communication with a server. I've reused this code multiple times, only changing the data and success function. However, every time I execute this function, I encounter an err ...

Transforming an HTML Attribute into a JavaScript Object

I'm encountering an issue with converting an HTML-data attribute into a JavaScript Object. Here is my approach: The data Attribute appears as: <a id="stringObj" data-string="{'Foo':'Bar'}">Some A-Tag</a> In JavaScri ...

Direct the user to a webpage with the option for postback functionality or caching

I'm encountering an issue on my webforms site with 2 menus. When a button is clicked on a page, it triggers some C# events through a webservice (ajax) and then redirects to another page using history.go(-1). The problem arises when I create a session ...

Utilize event delegation to retrieve the data attribute

Working great for me, able to access data-club-id: <!-- example --> <a class="clubCode" href="" data-club-id= "1234">join with the code</a> $("a.clubCode").on("click",function(e){ e.preventDefault(); var clubId = $(this) ...

Mastering the art of utilizing generic types efficiently within Higher Order Component structures

My parent component (Grid) passes props to a higher-order component (hoc), let me show you: <QuickBooksTable itemList={quickBooksList} /> Here is the QuickBooksTable component: export const QuickBooksTable = withIntegrationTable(props: : WithIntegra ...

Allow users to interact with table rows by making them clickable and sending a post parameter to a jQuery

After creating a table and populating it with elements using JSTL tags and EL expressions, the next step is to make each row clickable. This can be achieved by implementing the following function: $("tr").click(function() { window.location.href = $(th ...

Transforming FullCalendar (jquery) into asp.net (ashx)

///////////// Expert //////////////// $(document).ready(function() { var date = new Date(); var d = date.getDate(); var m = date.getMonth(); var y = date.getFullYear(); $('#calendar').fullCalendar({ ...

Tips for formatting input boxes on the client side

Q: How can I format my textbox so that when a user enters a number, such as one, it will be displayed as 0000001? The goal is to have any number entered be shown in 7-digit format. ...