import { Component } from '#angular/core';
import { NavController, Events, ModalController } from 'ionic-angular';
import * as SockJS from 'sockjs-client';
import { SomePage } from './somepage';
export class DashboardPage {
sockjs: any;
constructor(public navCtrl: NavController,
public events: Events,
private modalCtrl: ModalController) {
this.initWebsocket();
}
initWebsocket() {
this.sockjs = new SockJS('http://192.168.0.141:8080/ws-driver');
this.sockjs.onopen = function () {
console.log('open');
};
this.sockjs.onmessage = function (e) {
console.log('message', e.data);
alert('ok');
let model = this.modalCtrl.create(SomePage);
model.present();
};
this.sockjs.onclose = function () {
console.log('close');
};
}
}
alert('ok') had been process.
thanks
Use arrow functions instead of function keyword as this within the function refers to function object.
Try:
this.sockjs.onmessage = (e)=> {
console.log('message', e.data);
alert('ok');
let model = this.modalCtrl.create(SomePage);
model.present();
};
Or set self=this;
let self = this;
this.sockjs.onmessage = function (e) {
console.log('message', e.data);
alert('ok');
let model = self.modalCtrl.create(SomePage);
model.present();
};
Related
I'm building a chat app with Angular and Django using the get stream tutorial. https://getstream.io/blog/realtime-chat-django-angular/
However, I'm trying to run the app to create the chat view but it keeps saying 'messages' does not exist at the point marked 'this point' in the code.
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { MessageResponse, Channel } from 'stream-chat';
import { StreamService } from '../stream.service';
import { StateService } from '../state.service';
declare const feather: any;
#Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss'],
})
export class ChatComponent implements OnInit {
constructor(
public streamService: StreamService,
private stateService: StateService,
private router: Router
) {}
messages: MessageResponse[] = [];
message = '';
channel!: Channel;
async sendMessage() {
if (this.message) {
try {
await this.channel.sendMessage({
text: this.message,
});
this.message = '';
} catch (err) {
console.log(err);
}
}
}
getClasses(userId: string): { outgoing: boolean; incoming: boolean } {
const userIdMatches = userId === this.streamService.currentUser.messages.id; (this point)
return {
outgoing: userIdMatches,
incoming: !userIdMatches,
};
}
}
I have a basic serverless application below, I want to test using Jest if getUserById method is called. I am also using inversifyjs. Now when I run my test I am getting an error TypeError: Reflect.hasOwnMetadata is not a function. Another thing how can I mock a response here?
handler.spec.ts
import { IUsersHandler } from './../src/IUsersHandler';
import { UsersHandler } from './../src/UsersHandler';
import { APIGatewayProxyResult } from 'aws-lambda';
let handler: IUsersHandler;
let mockResponse: APIGatewayProxyResult;
describe("UsersHandler", () => {
beforeEach(() => {
handler = new UsersHandler();
});
it("should call getUserById method", () => {
const spy = jest.spyOn(handler, 'getUserById').mockImplementation(async () => mockResponse);
expect(spy).toBeCalledTimes(1);
});
});
UsersHandler Class
import { IUsersHandler } from './IUsersHandler';
import { injectable } from "inversify";
import { APIGatewayProxyHandler, APIGatewayProxyResult, APIGatewayProxyEvent } from "aws-lambda";
#injectable()
export class UsersHandler implements IUsersHandler {
constructor() { }
public getUserById: APIGatewayProxyHandler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
try {
return {
statusCode: 200,
body: JSON.stringify(event)
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify(err)
};
}
};
}
User Interface
import { APIGatewayProxyHandler } from 'aws-lambda';
export interface IUsersHandler {
getUserById: APIGatewayProxyHandler;
}
export const TUsersHandler = Symbol.for('IUsersHandler');
Handler.ts
import { IUsersHandler, TUsersHandler } from './src/IUsersHandler';
import { container } from "./src/inversify.config";
import 'source-map-support/register';
export const getUserById = async function (event, context, callback) {
const handler: IUsersHandler = container.get<IUsersHandler>(TUsersHandler);
return handler.getUserById(event, context, callback);
};
Final handler.spec.ts
import "reflect-metadata";
import { IUsersHandler } from "./../src/IUsersHandler";
import { UsersHandler } from "./../src/UsersHandler";
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
let handler: IUsersHandler;
let mockEvent: APIGatewayProxyEvent;
let mockResponse: APIGatewayProxyResult;
describe("UsersHandler", () => {
beforeEach(() => {
mockResponse = {
statusCode: 200,
body: "This is a test",
};
handler = new UsersHandler();
});
it("should call getUserById method", async () => {
const spy = jest
.spyOn(handler, "getUserById")
.mockImplementation(async () => mockResponse);
const response: any = await handler.getUserById(mockEvent, null, null);
expect(spy).toBeCalledTimes(1);
expect(response.body).toBe("This is a test");
expect(response.statusCode).toBe(200);
});
});
Help me fix the error, and if possible improve the test itself, because it will be based on further tests for services.
I hope for your help
This is my service file
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { createQueryBuilder, getConnection, getRepository, Repository, getManager, Connection } from 'typeorm';
import { Brands } from './brands/brands.entity';
import { Categories } from './categories/categories.entity';
import { Volumes } from './volumes/volumes.entity';
import { Packages } from './packages/packages.entity';
import { Tags } from './tags/tags.entity';
import { Countries } from './countries/countries.entity';
import { Sub_categories } from './sub_categories/sub_categories.entity';
import { Products } from './products.entity';
import { IProduct } from './products.interface';
import { Collections } from './collections/collections.entity';
#Injectable()
export class ProductsService {
constructor(
#InjectRepository(Products)
private productRepository: Repository<Products>,
) {}
private readonly products: IProduct[] = [];
async findAllProductsByCategory(category: string): Promise<IProduct[]> {
const qb = getRepository(Products).createQueryBuilder("products");
const subQuery: string = qb.subQuery()
.select('categories.id', 'cat_id')
.from(Categories, 'categories')
.where(`cat_id = '${ category }'`)
.getQuery()
return await this.findAllProductsByArgument( 'category_id', subQuery );
}
async findAllProductsByArgument(argumentId1: string, subQuery1: string, argumentId2?: string, subQuery2?: string): Promise<IProduct[]> {
const qb = getRepository(Products).createQueryBuilder("products");
qb
.select(
`*,
Products.brand_id AS brand_id`
)
.addSelect('brands.brand_name', 'brand_name')
.addSelect('brands.brand_id', 'brand_nameid')
.addSelect('categories.cat_name', 'cat_name')
.addSelect('categories.cat_id', 'cat_id')
.addSelect('volumes.volume_name', 'volume_name')
.addSelect('volumes.volume_id', 'volume_id')
.addSelect('tags.name', 'tag_name')
.addSelect('tags.tag_id', 'tag_nameId')
.addSelect('sub_categories.subcat_name', 'subcategory_name')
.addSelect('sub_categories.subcat_id', 'subcategory_id')
.addSelect('packages.package_name', 'package_name')
.addSelect('packages.package_id', 'package_nameId')
.addSelect('countries.country_name', 'country_name')
.addSelect('countries.country_id', 'country_nameId')
.addSelect('Products.price', 'price_by_one')
.innerJoin(Brands, 'brands', 'Products.brand_id = brands.id')
.innerJoin(Categories, 'categories', 'Products.category_id = categories.id')
.innerJoin(Volumes, 'volumes', 'Products.volume_id = volumes.id')
.innerJoin(Tags, 'tags', 'Products.tag_id = tags.id')
.innerJoin(Sub_categories, 'sub_categories', 'Products.sub_category_id = sub_categories.id')
.innerJoin(Packages, 'packages', 'Products.package_id = packages.id')
.innerJoin(Countries, 'countries', 'Products.country_id = countries.id')
.where('Products.stock > Products.pack_quantity AND isshow = true')
.andWhere(`Products.${ argumentId1 } = ${ subQuery1 }`);
if(argumentId2 && subQuery2){
qb.andWhere(`Products.${ argumentId2 } = ${ subQuery2 }`)
}
return qb.getRawMany();
}
}
I don't really understand how to mocking data and simulate functions
import { Test, TestingModule } from '#nestjs/testing';
import { getRepositoryToken } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { Products } from './products.entity';
import { ProductsService } from './products.service';
class ProductsFake {
public async find(): Promise<void> {}
}
describe('ProductsService', () => {
let service: ProductsService;
let repo: Repository<Products>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ProductsService,
{
provide: getRepositoryToken(Products),
useClass: ProductsFake
}
]
}).compile();
service = module.get(ProductsService);
repo = module.get(getRepositoryToken(Products));
});
describe('finding a products', () => {
it('should be defined', async () => {
expect(service).toBeDefined();
});
it('return the products list', async () => {
const product = new Products();
const mockData = {
id: 10,
brand_name: "Brewdog",
brand_nameid: "brewdog",
cat_id: "pivo"
};
Object.assign(product, mockData);
const productsRepositoryFindAll = jest
.spyOn(repo, 'find')
.mockResolvedValue([product]);
const result = await service.findAllProductsByCategory( 'pivo' );
expect(result[0]).toBe(product);
expect(productsRepositoryFindAll).toBeCalled()
});
});
});
This is an error that appears when trying to test
йййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййййй
Hi I need pass the data from one component to another, for this I am using the class BehavorSubject(I tried too with Subject class, but doesnt works for me). This is my code:
Home page has a filter, and when is selected a filter, it called the service and it service should change a variable of homePage
HomePage.ts
#Component({
providers: [PatientService],
})
export class HomePage {
subscription: Subscription;
constructor( public auth: AuthService,
public patientService: PatientService) {
this.subscription = this.patientService.nameGiven.subscribe(
nameGiven => {
this.patientsByElement = nameGiven.toString();
});
------ more code---
}
Filtro.ts
export class FiltroPage {
showFilter(filter : FiltroT): void{
... code ...
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.PatientService.getPatientsByTags(this.token,this.filterSelected);
} , 1000);
}
}
patient-service.ts
import { Subject } from 'rxjs/Subject';
import { Observable ,BehaviorSubject } from 'rxjs/Rx';
#Injectable()
export class PatientService {
nameSource = new BehaviorSubject("asd");
nameGiven = this.nameSource.asObservable();
this.nameSource.next('hi!!!'); //**it works but only in the constructor**
this.nameGiven.subscribe(()=>{
console.log("it changed");
});
getPatientsByTags(token: String, tags: Array<string>){
return new Promise(resolve => {
this.http.get(ConnectionParams.DevEnv + ProceduresNames.TagsByPatient + ProceduresNames.TagIdEtiqueta + tags, options)
.map(res => res.json())
.subscribe(data => {
if(data.data.poAnicuRegistros){
console.log("here")
this.nameSource.next('hi TON :/'); // <-- ***here is the problem. It doesnt work***
}
else
console.log("XX");
resolve( this.data);
});
});
}
}
Finally i didn't use the BehaviorSubject/Subject, i pass the data from the filter to Homepage of this way :
HomePage.ts
public popoverCtrl: PopoverController
//code ...
showFilter(myEvent) {
let popover = this.popoverCtrl.create(FiltroPage, {
showConfirm: (x) => {
//do something with the data received from the filter
}
});
popover.present({
ev: myEvent
});
}
Filter.ts
//code...
params: NavParams;
showConfirm() {// function that return the data to homePage
this.params.get('showConfirm')(this.patientsBytag);
}
I'm new with Ionic2 and I was following this tutorial and a simple test like
describe('Dummy test', () => {
it('should do nothing', () => {
expect(true).toBeTruthy();
expect(1 + 1).toBe(2);
});
});
works fine, but for some reason I keep getting this error when I try to follow the rest of the tutorial.
Component: Root Component
✖ initialises with a root page of LoginPage
Firefox 45.0.0 (Linux 0.0.0)
TypeError: win is undefined in src/test.ts (line 937)
My src/test.ts is the same as the tutorial and it doesn't have any win in it. My app.spec.ts is this
import { TestBed, ComponentFixture, async } from '#angular/core/testing';
import { IonicModule } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { UserData } from '../providers/user-data';
import { LoginPage } from '../pages/login/login';
import { Platform } from 'ionic-angular';
import { MyApp } from './app.component';
import { LoginPage } from '../pages/login/login';
let comp: MyApp;
let fixture: ComponentFixture<MyApp>;
describe('Component: Root Component', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp],
providers: [
StatusBar,
SplashScreen,
UserData,
Platform
],
imports: [
IonicModule.forRoot(MyApp)
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
comp = fixture.componentInstance;
});
afterEach(() => {
fixture.destroy();
comp = null;
});
it('initialises with a root page of LoginPage', () => {
expect(comp['rootPage']).toBe(LoginPage);
});
});
And my app.component.ts is this
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { MenuSidePage } from '../pages/menu-side/menu-side';
import { LoginPage } from '../pages/login/login';
import { UserData } from '../providers/user-data';
#Component({
template: `<ion-nav #nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage: any;
constructor(
public platform: Platform,
public statusBar: StatusBar,
public splashScreen: SplashScreen,
private userData: UserData,
) {
platform
.ready()
.then(() => {
//First - check if user is logged
if(this.userData.currentUser) {
this.rootPage = MenuSidePage;
} else {
this.rootPage = LoginPage;
}
statusBar.styleDefault();
splashScreen.hide();
});
}
}
I don't have yet the solution, but you shouldn't use compileComponents() 'cause you are using a template and not a templateUrl like said in this tutorial :
"We need to use compileComponents when we need to asynchronously compile a component, such as one that has an external template (one that is loaded through templateUrl and isn’t inlined with template). This is why the beforeEach block that this code runs in uses an async parameter – it sets up an asynchronous test zone for the compileComponents to run inside."
Hope it's a kind of helping :)
The win() function come from the Plaftorm, you have to mock it as follow :
export class PlatformMock {
public ready(): Promise<string> {
return new Promise((resolve) => {
resolve('READY');
});
}
public getQueryParam() {
return true;
}
public registerBackButtonAction(fn: Function, priority?: number): Function {
return (() => true);
}
public hasFocus(ele: HTMLElement): boolean {
return true;
}
public doc(): HTMLDocument {
return document;
}
public is(): boolean {
return true;
}
public getElementComputedStyle(container: any): any {
return {
paddingLeft: '10',
paddingTop: '10',
paddingRight: '10',
paddingBottom: '10',
};
}
public onResize(callback: any) {
return callback;
}
public registerListener(ele: any, eventName: string, callback: any): Function {
return (() => true);
}
public win(): Window {
return window;
}
public raf(callback: any): number {
return 1;
}
public timeout(callback: any, timer: number): any {
return setTimeout(callback, timer);
}
public cancelTimeout(id: any) {
// do nothing
}
public getActiveElement(): any {
return document['activeElement'];
}
}
Here is the link to see a project for real integration of this mock class.
Hope it helps :)