How can I dynamically insert an HTML tag from a database into my directive's template to define the root element/tag of the template?

I am looking to create a dynamic template using data from a database (specifically Firebase/angularFire). The structure of the template will be determined by the tag property within each object retrieved with angularFire. Initially, I tried:

var imgTemplate = function(tag){
  return '<'+tag.tag+' class="{{ tag.classes }}" src="{{ tag.content }}" alt="{{ tag.alt }}">';
};
var txtTemplate = function(tag){
  return '<'+tag.tag+' class="{{ tag.classes }}">{{ tag.content }}</'+tag.tag+'>';
};

However, this approach did not work as expected because tag.tag was undefined since the compile function runs before angularFire fetches the data and binds it. Here is my second attempt:

var imgTemplate = function(tag){
  return '<{{tag.tag}} class="{{ tag.classes }}" src="{{ tag.content }}" alt="{{ tag.alt }}">';
};
var txtTemplate = function(tag){
  return '<{{ tag.tag }} class="{{ tag.classes }}">{{ tag.content }}</{{ tag.tag }}>';
};

This solution only partially renders the template:

<{{ tag.tag }} class="{{ tag.classes }}">{{ tag.content }}

for each 'tag' element iterated over with ng-repeat instead of generating the actual HTML.

This is the compile function of my directive:

  compile: function(templateElem, directiveAttrs){
    var tag = directiveAttrs.tag;
    if(tag.tag === 'img'){
      var img = angular.element(imgTemplate(tag));
      templateElem.replaceWith(img);
    }else{
      var txt = angular.element(txtTemplate(tag));
      templateElem.replaceWith(txt);
    }
  },

The data is fetched from Firebase in a controller of an angular.ui.router's state:

.state("siteNav.sideNav.content", {
  url: '/:lang/:view/:contentID/:index',
  views:{
    '@': {
      templateUrl: '/views/content.html',
      controller: function($scope, angularFire){
        var stateParams = $scope.$stateParams;
        console.log(stateParams.lang);
        var url = 'https://example.firebaseio.com/'+stateParams.lang+'/content/'+stateParams.view+'/'+stateParams.contentID;
        angularFire(new Firebase(url), $scope, 'tags');
      }
    }
  }
}

The content of template content.html is as follows:

<div ng-repeat="tag in tags">
  <acms-view tag="tag"></acms-view>
</div>
  • I require the three-way binding functionality provided by angularFire.
  • The tag must come from Firebase, so I cannot use a literal value instead.

How can I make sure that the 'tag' property is populated before the compile function uses it for comparison or value assignment?
I cannot use the angularFire service within the compile function as there is no scope to bind the fetched data to.
Even though angularFire does not work within the linking function, using Firebase's JavaScript API could be a potential solution. However, how would I achieve the three-way binding offered by angularFire?
Thank you for your assistance
Jared

Answer №1

To create a promise using $q and set $scope.tags to be a promise that returns the data once angularFire retrieves it, follow these steps:

.state("siteNav.sideNav.content", {
  url: '/:lang/:view/:contentID/:index',
  views:{
    '@': {
      templateUrl: '/views/content.html',
      controller: function($scope, $q, angularFire){
        var stateParams = $scope.$stateParams;
        var url = 'https://example.firebaseio.com/'+stateParams.lang+'/conten /'+stateParams.view+'/'+stateParams.contentID;
        var deferred = $q.defer();
        $scope.tags = deferred.promise;
        angularFire(new Firebase(url), $scope, 'rawTags').then(function() {
          deferred.resolve($scope.rawTags);
        });
      }
    }
  }
}

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

Sharing a scope variable among ng-app modules in AngularJS

Is it possible to have two separate ng-apps running on the same page? bookingApp calendarApp I am looking for a way to share a selected date scope variable from calendarApp with bookingApp. Any ideas on how to achieve this functionality? Thank you, Gla ...

The file reader feature is currently experiencing issues on both Chrome and Internet Explorer browsers

After uploading an image file from my PC, I convert it to a data URL and then use the img element to preview it. Surprisingly, this process works perfectly fine in Firefox. However, when I try to do the same in Chrome or IE, the src attribute of the img el ...

Enhancing AutoComplete Functionality with Jquery Using a JSON Array String

<script> $(function () { var myData = '[{"OriginId":2609,"OriginName":"14th Mile Stone"},{"OriginId":2007,"OriginName":"Aachara"},{"OriginId":2220,"OriginName":"Aarni"},{"OriginId":2216,"OriginName":"Aasind"},{"OriginId":637 ...

Is it better to store JSON data locally using cookies or HTML5 local storage?

Currently, I am working on developing a mobile website using jquery mobile. My main concern right now is how to efficiently carry JSON data across multiple pages. I am debating whether it would be better to store this JSON data in a cookie or use HTML5 loc ...

What is the best way to use multiple encoding types when sending data via a POST method in Node.js?

My current challenge involves sending a combination of name and description text data alongside a video file. Unfortunately, I've encountered an issue where I can only send either the video or the text, but not both simultaneously. Below is the code ...

What could be causing my randomly generated value to be overwritten so quickly?

I'm encountering an issue with my code. I am attempting to generate objects in random locations using drawHyperBall(), getRandomIntX(), and getRandomIntY(). However, the random value seems to be constantly overwritten. How can I resolve this problem? ...

Utilize data retrieved from an API to customize the appearance of buttons through the combination of React and Sass styling techniques

I retrieved data from an API and used it to create a list of buttons. The data I received includes names and color codes. { name: "bob", colorCode: "#DC7472" }, { name: "ben", colorCode: "#69DCD1" }, { name: &q ...

ajaxStart event does not trigger when making an Ajax POST request

My ajaxStart event functions properly for ajax loads, but it does not work at all when I do a POST request. The following code is consistently rendered on all pages: $(document).ajaxComplete(function () { hideIcon(); if (stepState !== &a ...

Arrange the JSONB data type with sequelize literal in your order

My current approach involves querying for all items using the following structure: const filteredItems = await allItems.findAll({ where: conditions, include: associations, order: sortingCriteria, limit: limit, o ...

Preserving user interaction history in the browser while syncing with the server in AngularJS

My current challenge involves handling an HTML form that is connected to an object named a through an ngModel. When a user updates the data in the form, I send a PUT request to update the resource on the server. The response from the server contains update ...

Is there a way to switch the language on the date-picker tool?

My date-picker has a unique set up: <input type="text" ng-readonly="true" class="form-control" datepicker-popup="yyyy-MM-dd" ng-model="filter.FInicial" is-open="filter.controlFInicialAbierto" min-date="minDateIni" max-date="maxDat ...

Showing a Javascript Object on an HTML Page

I am looking to showcase the "users email" directly on my HTML page as plain text. Currently, my project involves three distinct files: index.html - edit.html - my_parse_app.js Within my_parse_app.js, I define all my JavaScript and jQuery functions for ...

Unable to assign a value to a property within a JavaScript object

I'm attempting to configure settings for a JavaScript object (my assumption is that it's not a plain JS Object, but possibly an instance of a specific class, though I haven't been able to identify the class). https://i.sstatic.net/xsUiJ.png ...

Troubleshooting problems with rendering DropInBlog in Docusaurus

Seeking to integrate DropInBlog with Docusaurus in lieu of using its default blog feature. DropInBlog claims that the implementation should be straightforward. Add a script tag to the page body where the blog will be displayed. It will look something l ...

Error encountered during navigation: navigator has not been defined

I encountered an issue where the page gets redirected upon form submission without triggering the catch block. However, in the backend, I am facing an error stating that the API body is not being executed. Below is the code snippet of the page: "use cl ...

Guide to enabling cross-domain uploads of files

After following a tutorial, I successfully implemented an HTML5 uploader on my website. The source of the tutorial can be found here: The uploader works perfectly; however, I am now facing an issue where I want to upload files to a different domain. Accor ...

When attempting to display a JSON array, a variable defined as numeric transforms into NaN

I'm attempting to split a JSON array into three-column Bootstrap rows using the code below. My approach involves increasing a numeric variable to 3, adding a new row div, and then setting it back to 1. However, I am encountering an issue where the va ...

Is there a way to customize localization arguments for Firebase Cloud Messaging on iOS?

I'm currently working on creating localized push notifications for iOS using FCM. I am having trouble determining the correct message format. Here is how I have structured it at the moment: async function sendLocationLostNotification(notificationToke ...

What is the best way to have the slide shift to the left solely after the initial click and prevent it from moving left on subsequent clicks?

Is there a way to prevent the slide area from scrolling left when the left button is clicked before it has been scrolled right first? Additionally, how can we lock the scroll after it reaches the last div? var $slider = $("#recent-container") $("#right ...

Trigger a child-mounted event and retrieve it from the parent component

Imagine I have a component named child. There is some data stored there that I need to retrieve in the parent component. To accomplish this, I plan to emit an event in the childs mount using this.$emit('get-data', this.data), and then receive it ...