Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs test if file exists for ng-include

Tags:

angularjs

I am using ng-include to bring in a partial in an AngularJS app. If the partial .html file doesn't exist, I would like to do something else.

The partial name is extracted from the $location.path(). So if the path is "/foo", then I would like use "my_partial_foo.html". However if "my_partial_foo.html" doesn't exist, then I'd like to use "my_partial_default.html" instead.

I'm putting this data into a $dialog, so I can't use the typical routeProvider functionality (afaik).

My main question is: How do I determine if "my_partial_foo.html" exists before I use it in an ng-include directive?

Related questions:

angular - reusable dialogs

How to prepopulate a dialog in angularjs/bootstrap

like image 776
Josh Petitt Avatar asked Oct 04 '22 10:10

Josh Petitt


2 Answers

Something like this might work. Basically the $templateCache will always have a key for my_partial_foo.html (so your ng-include can always reference it) but the value might be the default or the real thing.

var app = angular.module('myapp', []).run(function($templateCache,$http){
  $http.get('my_partial_foo.html',
    //success
    function(data){
      $templateCache.put('my_partial_foo.html', data);
    },
    //failure
    function(){
      $http.get('my_partial_default.html', function(data){
        $templateCache.put('my_partial_foo.html', data);
      });
    });
});
like image 165
mdonovan2010 Avatar answered Oct 07 '22 18:10

mdonovan2010


I had a similar need but found the built-in $templateCache & ui.router's $templateFactory to have inconsistent behavior. When I'd use this...

$templateFactory.fromUrl( './non-existant.html' )
.catch( function( err ){ console.log( 'does not exist' )})

...it would fail to trigger the catch callback. It was only after hitting this call twice would the error get triggered.

So I rolled my own solution using $q and XMLHttpRequest:

.service( 'templateUtils', [
    '$q'
    function( $q ){
        var api = {
             hasTemplate: function( url ){
                  var d = $q.defer()
                  var rqst = new XMLHttpRequest()
                  rqst.open( 'GET', url )
                  rqst.onload = function( evt ){
                       if( evt.target.status === 200 )
                           d.resolve( true )
                       else
                           d.reject( false )
                  } 

                  return d.promise
             }
        }

        return api
    }
])

I use this like so...

var templateUrl = './default-template.html'

templateUtils.hasTemplate( urlToCheck )
.then( function( rsp ){ templateUrl = './different-template.html' })
like image 33
jusopi Avatar answered Oct 07 '22 17:10

jusopi