Spec Has No Expectations error on Angular 2 templateUrl - jasmine

I have a angular 2 Component MyComp
#Component({
selector: 'myform',
templateUrl: './myform.html',
providers: [HTTP_PROVIDERS],
directives: [ROUTER_DIRECTIVES]
})
This is my spec.
it('should work', injectAsync([TestComponentBuilder], (tcb) => {
return tcb.createAsync(MyComp).then((fixture) => {
fixture.detectChanges();
expect(1+ 1).toEqual(2);
});
}));
When i execute the tests its giving me an error
Can't bind to 'ngForOf' since it isn't a known native property
The actual code works, but its only the tests that are failing,
Update :
Spec works if i replace templateUrl with template.
i.e if i just try with
template: <h1>Fake</h1> <ul> <li *ngFor="#item of items"> </li> </ul>
Interested to know if anyone has tested components with templateUrl with angular 2.0 beta version.
Thanks !

You should add ngFor or CORE_DIRECTIVES to the component directives:
import { CORE_DIRECTIVES } from 'angular2/common';
#Component({
selector: 'myform',
templateUrl: './myform.html',
providers: [HTTP_PROVIDERS],
directives: [ROUTER_DIRECTIVES, CORE_DIRECTIVES] // <- HERE!!!
})
export class MyForm { /* ... */ }
or
import { NgFor } from 'angular2/common';
#Component({
selector: 'myform',
templateUrl: './myform.html',
providers: [HTTP_PROVIDERS],
directives: [ROUTER_DIRECTIVES, NgFor] // <- HERE!!!
})

Related

MSTeams Config page Angular 12 SPA with routing

I'm using Angular 12 and am writing a simple group tab app. I'm working on the config page component and the html looks like this:
<br />
<br />
<br />
<p>Configuration 3</p>
<input type="text" placeholder="Some Test" />
In a normal browser, the text and box appears. But if I try to do the same thing via the install to tab path, I don't get the text or input box at all.
I think this might have something to do with routing but can't confirm.
The app-routing-module is pretty simple:
const routes: Routes = [
{
path: '',
component: HomeComponent,
},
{
path: 'configuration',
component: ConfigurationComponent,
},
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {
initialNavigation:
!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup()
? 'enabled'
: 'disabled',
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
So what does it take to get the SPA to route to the configuration page when used within teams?
Configuration Component: (URL purposed changed to protect the innocent)
import { Component, OnInit } from '#angular/core';
import { Inject, AfterViewInit, ElementRef } from '#angular/core';
import { DOCUMENT } from '#angular/common';
import * as microsoftTeams from '#microsoft/teams-js';
#Component({
selector: 'app-configuration',
templateUrl: './configuration.component.html',
styleUrls: ['./configuration.component.scss'],
})
export class ConfigurationComponent implements OnInit, AfterViewInit {
constructor(
#Inject(DOCUMENT) private document: Document,
private elementRef: ElementRef
) {}
ngOnInit(): void {
microsoftTeams.initialize();
}
ngAfterViewInit() {
console.log('Initializing ms teams');
microsoftTeams.settings.registerOnSaveHandler((saveEvent) => {
microsoftTeams.settings.setSettings({
entityId: '',
contentUrl: 'https://test.ngrok.io',
suggestedDisplayName: 'Test',
websiteUrl: 'https://test.ngrok.io',
});
saveEvent.notifySuccess();
});
console.log('Register on save');
microsoftTeams.settings.setValidityState(true);
}
}
Thanks,
Nick
In order to render a tab in Teams. You need to make sure that it is iFramable. Please see the document- Tab requirements.
Make sure that you have given the domain in valid domains in your manifest.
Please share more details like console error, what are you using static tab or config and manifest, if issue isn't solve for you
I traced my problem for this particular question to the line:
initialNavigation:
!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup()
? 'enabled'
: 'disabled',
This example is in a lot of the code for SPAs in and Teams Tabs.
I just have it set to 'enabled' for now and I can get beyond the purpose of this question.

Custom validator in angular reactive forms is never firing

I have created a very simple custom validator for a simple form control, e.g. MatInput, which would always return non-null e.g. invalid. I hav also added one of the pre-built validators e.g. required. When I start my app I can see that status = INVALID and errors.required = true.
Once I start typing, I expected that status will remain INVALID and errors.myError = true, but this does not happen. What am I doing wrong? I have built my example on StackBlitz. I have also added the contents on my TS & HTML files below
TS
import { Component } from '#angular/core';
import { AbstractControl, FormControl, ValidationErrors, ValidatorFn, Validators} from '#angular/forms';
export function myValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
return { "myError": true };
};
}
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = new FormControl('', [Validators.required, myValidator]);
}
HTML
<label>
Name:
<input type="text" [formControl]="name">
</label>
{{ name | json }}
I am quite new to Angular and I am not sure how to debug this. What can I try next?
TL;DR:
export class AppComponent {
name = new FormControl('', [Validators.required, myValidator()]);
}
Explanation:
myValidator is not being called, so you are not getting the ValidatorFn

Is there a specific way of using nativescript-videorecorder plugin to work with angular?

I am unable to get the nativescript-videorecorder to work in my app.
I had installed the plugin and used the code given on the github https://github.com/triniwiz/nativescript-videorecorder for typescript. I created a simple HTML ui and tried to call a function to open the camera to record video. However it is does not work
For app.component.html i used the tag <Image src="videoCam" (tap)="onCam()">
For app.component.ts i used the below code
import { VideoRecorder, Options as VideoRecorderOptions } from 'nativescript-videorecorder';
#Component({
moduleId: module.id,
selector: "ns-app",
templateUrl: "app.component.html"
})
export class AppComponent {
export class AppComponent {
onCam() {
const options: VideoRecorderOptions = {
hd: true
saveToGallery: true
};
const videorecorder = new VideoRecorder(options);
videorecorder.record().then((data) => {
console.log(data.file)
}).catch((err) => {
console.log(err)
});
}
}
Is there anything i am missing to get this to work ?

handling link opening event in HtmlView

I have a html code that has a link inside it. code below is my template:
<HtmlView [html]="htmlString" ></HtmlView>
this is my component:
import { Component } from "#angular/core";
#Component({
moduleId: module.id,
templateUrl: "./creating-htmlview.component.html"
})
export class CreatingHtmlViewExampleComponent {
public htmlString: string;
constructor() {
this.htmlString = 'google';
}
}
how to handle a element inside of HtmlView when it run ? there is a way to detect when user run the link?
That's not supported yet, there is an open feature request. You may write a plugin that implements native apis like ClickableSpan or Linkify.

"No provider for MdDialogRef!"

Suppose I have this component:
#Component({
selector: 'pizza-dialog',
template: `
<h1 md-dialog-title>Would you like to order pizza?</h1>
<md-dialog-actions>
<button (click)="dialogRef.close('yes')">Yes</button>
<button md-dialog-close>No</button>
</md-dialog-actions>
`
})
export class PizzaDialog {
constructor(public dialogRef: MdDialogRef<PizzaDialog>) { }
}
I've already imported MdDialog into my app module:
#NgModule({
imports: [
BrowserModule,
MaterialModule.forRoot(),
MdDialogModule.forRoot(),
],
...
})
Why would I get this error?
No provider for MdDialogRef!
You may have tried to use your dialog component in a template like this:
<pizza-dialog ...></pizza-dialog>
Delete that from your template and open the dialog using MdDialog.open() as is done here:
#Component({
selector: 'pizza-component',
template: `
<button type="button" (click)="openDialog()">Open dialog</button>
`
})
export class PizzaComponent {
dialogRef: MdDialogRef<PizzaDialog>;
constructor(public dialog: MdDialog) { }
openDialog() {
this.dialogRef = this.dialog.open(PizzaDialog, {
disableClose: false
});
this.dialogRef.afterClosed().subscribe(result => {
console.log('result: ' + result);
this.dialogRef = null;
});
}
}
This code was copied from:
https://github.com/angular/material2/blob/master/src/lib/dialog/README.md
You must not change your implementation.
You can provide a Mock for the MdDialogRef.
In the following example I fake the MdDialogRef with the MdDialogRefMock class and register it in the providers section:
import { async, ComponentFixture, TestBed } from "#angular/core/testing";
import { CUSTOM_ELEMENTS_SCHEMA } from "#angular/core";
import { MessageBoxYesNoComponent } from "./message-box-yes-no.component";
import { MdDialogRef } from "#angular/material";
class MdDialogRefMock {
}
describe("MessageBoxYesNoComponent", () => {
let component: MessageBoxYesNoComponent;
let fixture: ComponentFixture<MessageBoxYesNoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MessageBoxYesNoComponent ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [
],
providers: [
{ provide: MdDialogRef, useClass: MdDialogRefMock }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MessageBoxYesNoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});
If you are using Jasmine, you can also create a Spy instead of creating the Fake-Class:
let mdDialogSpy = jasmine.createSpy('MdDialogRef');
Remove <pizza-dialog ...></pizza-dialog> from the template, it only require the button that open the Dialong because in the code you set the relation with the dialog.
Add MdDialogRef to providers of your module

Resources