Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[$compile:tpload] Failed to load template #209

Open
ptomaszi opened this issue Sep 18, 2017 · 2 comments
Open

[$compile:tpload] Failed to load template #209

ptomaszi opened this issue Sep 18, 2017 · 2 comments

Comments

@ptomaszi
Copy link

The component I am testing is using the "templateUrl" to provide a template:

import { Component, Inject, Input, Output, EventEmitter, OnChanges } from 'ng-metadata/core';

@Component({
    selector: 'diContactList',
    templateUrl: 'src/app/portal/parties/contacts/list/contact-list.component.html'
})
export class ContactListComponent implements OnChanges {

Then I have a corresponding unit test:

import { bundle, getInjectableName, NgModule, Component } from 'ng-metadata/core';

describe('ContactListComponent', () => {
    @Component({
        selector: 'test-component',
        template: `
            <di-contact-list>
            </di-contact-list>`
    })
    class TestComponent {
        constructor() {}
    }
    @NgModule({
        declarations: [TestComponent, ContactListComponent]     
    })
    class TestNgModule { } 
    
    let $compile: ng.ICompileService;
    let $rootScope: ng.IRootScopeService;
    let $scope: ng.IScope;
    let render: IRender<TestComponent>;
    let sut: ContactListComponent;
    
    beforeEach(() => {
        const TestModule: string = bundle(TestNgModule).name;
        ng.mock.module(TestModule);
    });

    beforeEach(ng.mock.inject(function($injector: ng.auto.IInjectorService) {
        $compile = $injector.get<ng.ICompileService>('$compile');
        $rootScope = $injector.get<ng.IRootScopeService>('$rootScope');
        $scope = $rootScope.$new();
        
        render = renderFactory($compile, $scope);
        sut = render(ContactListComponent).ctrl;
    }));

When run I am getting the following error:

Error: [$compile:tpload] Failed to load template: src/app/portal/parties/contacts/list/contact-list.component.html (HTTP status: undefined undefined)
http://errors.angularjs.org/1.6.5/$compile/tpload?p0=src%2Fapp%2Fportal%2Fparties%2Fcontacts%2Flist%2Fcontact-list.component.html&p1=undefined&p2=undefined

When I remove templateUrl or replace with template in the component, unit tests run correctly.

@aciccarello
Copy link
Collaborator

aciccarello commented Sep 18, 2017

Hello, this shouldn't be any different than testing normal AngularJS components. If you want to test the component template you will need to populate the template cache with the template for that path. Depending on your build system there are several ways you can do that.

https://blog.logentries.com/2015/03/template-caching-in-angular-how-to-avoid-the-storm/

@ptomaszi
Copy link
Author

I have found where the issue was. If my component is using the "templateUrl" instead of "template", the render function returns "undefined" for the "ctrl". I have fixed it by modifying "src/testing/utils.js" file and adding "$scope.$digest();" after the $compile:

function renderFactory($compile, $scope) {
    return _compileAndDigest;
    function _compileAndDigest(Directive, _a) {
        var _b = _a === void 0 ? {} : _a, jqHost = _b.jqHost, attrs = _b.attrs, jqChildren = _b.jqChildren;
        var ctrlName = provider_1.getInjectableName(Directive);
        var selector = primitives_1.StringWrapper.kebabCase(ctrlName);
        // is Directive
        if (jqHost) {
            jqHost.attr(selector, '');
        }
        else {
            // is Component
            var hostElement = "<" + selector + "></" + selector + ">";
            jqHost = lang_1.global.angular.element(hostElement);
        }
        // since attributes can be undefined we check them
        if (attrs) {
            jqHost.attr(attrs);
        }
        if (jqChildren) {
            jqHost.append(jqChildren);
        }
        // angular api
        var compiledElement = $compile(jqHost)($scope);
        $scope.$digest();
        var ctrl = compiledElement.controller(ctrlName);
        $scope.$apply();
        return { compiledElement: compiledElement, ctrl: ctrl };
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants