Trouble retrieving the resolved value of a factory method that utilizes promises in a directive's templateUrl in AngularJS

Currently, I am working on a highly modularized project and focusing on building an Element Directive that dynamically changes the templateUrl based on user login/logout.

To achieve this, I am attempting to execute a Factory's Function within the templateUrl. This specific function calls another method from a JWT Factory and returns true if the user is logged in or false if not.

Based on the result received in the templateUrl, I need to choose between different urls for rendering purposes.

Unfortunately, I encountered the following error:

[$http:badreq] Http request configuration url must be a string.  Received: {}

All $log.log() statements display the correct results.

However, the problem persists as it fails to render either page1 or page2.

Directive

(function () {
  'use strict';

  angular
    .module('myApp')
    .directive('myDirective', ['SessionCheckerFactory',  function (SessionCheckerFactory) {

      return {
        restrict: 'E',
        templateUrl : function(){
          return SessionCheckerService.checkSession().then( function (res) {
            console.log(res);//true
            return res ? 'app/page1.html' : 'app/page2.html';
      });
        },
        controller       : 'MyController',
        controllerAs     : 'myCtrl',
        bindToController : true

      };
    }]);
})();

SessionCheckerFactory

(function () {
  'use strict';

  angular
    .module('myApp')
    .factory('SessionCheckerFactory', function (AuthTokenFactory) {

      function checkSession() {
          return AuthTokenFactory.isAuth();
      }          

      return {
        checkSession: checkSession
      }

    });
})();

AuthTokenFactory

(function() {
  'use strict';

  angular.module('myApp')
  .factory('AuthTokenFactory', function AuthTokenFactory(store, $cookies) {

      //Takes user's info from LocalStorage, if not empty returns a String with encoded string informations
      function getToken() {
       if (store.get(key)) {
         return store.get(key);
       }
        //Takes user's info from cookie
        var token = $cookies.get('token', {path: '/'});
        store.set(key, token);

        return token;
      }

      //If getToken is empty returns false, else true
      function isAuth() {
        return Promise.resolve(Boolean(getToken()));
      }

      return { 
              isAuth   : isAuth,
              getToken : getToken
      }
 });
})();

I have researched and found that similar errors are typically related to $http requests, but my case seems different. Unfortunately, I have not been able to find a solution yet.

Any suggestions on how to resolve this issue?

Thank you in advance.

Answer №1

When my templateUrl receives the value true, a specific URL is chosen; if false, a different one is chosen.

In reality, it's not quite that simple. If you receive true, you choose one URL, for any truthy value you pick another URL, and if it's falsy then no URL is picked at all:

 if (res) {
     if (res === true) {
         return resolve('app/page1.html');
     } // else
         return resolve('app/page2.html');
 }
 // else return undefined;

To address this issue, consider using the following code snippet instead:

templateUrl: function(){
    return SessionCheckerFactory.checkSession().then(function (res) {
        if (res) {
            return 'app/page1.html';
        } else {
            return 'app/page2.html';
        }
    })
},

Answer №2

The issue was successfully resolved by implementing a custom link function along with the use of $templateRequest

Custom Directive Implementation

link: function (scope, element) {
      SessionCheckerService.renderTemplate().then(function (temp){
        $templateRequest(temp).then(function (requestedTemplate) {
          element.html(requestedTemplate);
          $compile(element.contents())(scope);
        });
      });
    }

Factory Methods for Template Handling

var templateConfig = './app/config/templates.config.json';

function getTemplate(){
  return $http.get(templateConfig)
    .then(function(templates) {
      return templates.data;
    });
}

function checkSession() {
  return Promise.resolve(AuthTokenFactory.isAuth());
}

function whichTemplate(template, result) {
  var myTemplate = '';
  if(result){
     myTemplate = template.logIn;
  } else {
     myTemplate = template.logOut;
  }
    if(myTemplate){
       return Promise.resolve(myTemplate);
    }

 }

//Chaining the methods and returning the correct template
function renderTemplate() {
  return new Promise(function (resolve) {
     checkSession().then(function(isAuth){
       getTemplate().then( function(templates){
         whichTemplate(templates, isAuth).then( function (temp) {
           return resolve(temp);
         });
       });
     });
   });
 }

 return {
   renderTemplate : renderTemplate
 }

Templates Configuration Settings

{
  "logOut" : "app/page1.html",
  "logIn"  : "app/page2.html"
}

This solution should be beneficial in similar scenarios.

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

AngularJS fetches the 'compiled HTML'

If I have this angularjs DOM structure <div ng-init="isRed = true" ng-class="{'red': isRed == true, 'black': isRed == false}"> ... content </div> How can I obtain the 'compiled' version of this on a cl ...

Accessing Facebook through Login with only a button visible

I need help with checking the user's login status on Facebook. I have implemented the code provided by Facebook, but all I see is the login button. How can I determine if the user is already logged in or not? function testAPI() { console.log(&apo ...

The process of overriding CSS applied through JavaScript

I am using a third-party multi-select dropdown. Similar to Select2, the multi-select dropdown is created using JQuery with select2.min.js and the width of the dropdown is automatically calculated. Is there any way to apply static width to it, as I believe ...

issue with AngularJS custom blur functionality not functioning as expected

I have been attempting to set up notifications similar to this example: http://plnkr.co/edit/GbFioFDNb2OC4ZjARQTp?p=preview However, I have been unable to integrate it into my script successfully. When I click outside the notification box, nothing happen ...

Jquery trigger causing href links to malfunction

Here is a JavaScript example: var sampleFunction = function(){ return { initialize : function(data) { this.sendRequest({ action : 'login' }); }, loginAction : function() { ...

Using AngularJS UI Bootstrap tooltips in conjunction with Bootstrap 4: A complete guide

When using the directive <div uib-tooltip="hello-world" tooltip-is-open="true">hello world</div>, an error occurs: Failed to load template: uib/template/tooltip/tooltip-popup.html This website is utilizing both ui-bootstrap.js and ui-bootstra ...

Every time Jquery tries to retrieve cookies, it consistently returns as undefined

Having trouble accessing Application cookies using jquery in my Asp.Net MVC App. Check out this Screenshot of Cookie and its Value. I've been trying to access the Cookie with $.cookie('ASP.NET_SessionId'); but it keeps returning "undefined" ...

Is it possible to implement MV* in Polymer using models and services as polymer elements?

Imagine I want two views (polymer-elements) to share a model, how can this be achieved? In Angular, the model would reside in a singleton service that is injected into the views, allowing both views to access the same data source. I attempted to replicat ...

What could be causing my AngularJS code to malfunction?

I am having trouble with this code that is supposed to retrieve data from my web API. Despite checking multiple times, it still doesn't seem to be working. Can someone please assist me in identifying any mistakes in the code? var MyApp = angular.modu ...

Setting up a Bootstrap tokenfield for usage with a textarea

I was attempting to set up a tokenfield on a textarea with increased height, but it is showing up as a single-line textbox. How can I modify the tokenfield to function properly with a textarea? <textarea name="f1_email" placeholder="Enter Friends' ...

Strategies for analyzing Authorize.net payment responses in Ionic and JavaScript

Despite numerous attempts, I am struggling to parse the response from the authorize.net payment gateway. Below is the primary response from authorize.net: "{"transactionResponse":{"responseCode":"1","authCode" ...

Trigger a series of functions upon clicking with ReactJS

Need some assistance with an alert message functionality. I have a button labeled Checkout, and when clicked, it should clear the cart and display an alert. At present, the individual functions work as expected - calling emptyCart() works fine, and calling ...

The jQuery Select2 Plugin for Dynamic Dropdowns with Ajax Integration

Utilizing the Select2 plugin with Ajax to connect to my employee database has been quite helpful. It allows setting up a meeting and selecting all the employees you wish to invite. Here is an example of the code: $("#requiredAttendees").select2({ ...

Deliberately "locking" a JavaScript variable with a immediately-invoked function expression

While browsing through a blog post here that discusses creating a web scraper using node.js, I stumbled upon an intriguing piece of javascript that has left me somewhat perplexed. This particular snippet of code seems like something I could implement in my ...

Getting a variable from outside of the observable in Angular - a step-by-step guide

I have an Observable containing an array that I need to extract so I can combine it with another array. this.builderService.getCommercialData() .subscribe( data=>{ this.commercialDetails = data; this.commercialDetailsArr ...

Transforming CSV files into JSON format using d3.js

I'm encountering an issue when attempting to convert CSV to JSON. The following is the snippet of code I am using for the conversion: d3.csv("http://localhost:8080/Sample/flight.csv", function(flights) { //alert(flights); ...

Find unique numbers within a specified range using NodeJS

I need to update my arts on an NFT test via OpenSea API, but I'm facing an issue where the numbers are being repeated. Is there a way to select a number within a range that does not repeat? Here is my current code: const opensea = require("opense ...

Is there a way to verify if the request query value is empty like ""?

When creating a Node.js component, I encountered an issue with one of my APIs that sometimes returns empty query values like "". In order to handle this scenario, I need to implement a conditional statement. For example, the query may look like this: { ...

Inability to submit page after clicking on lower half of button while eliminating validations

In my current Struts2 application, I am encountering a issue related to validations on textfields. The validations include checks for missing values and incorrect values. Below these fields, there is a button that should submit the form once all validation ...

The location of errors is not displayed in VueJS stack traces

My Current VueJS Setup Check out the Source Code here I am working on a project using VueJS with webpack. I have chosen not to use the vue-loader plugin or .vue files. My project structure resembles a typical Javascript webpack project where I import vu ...