GeolocationPositionError is not defined - geolocation

I'm using GeolocationPositionError which should be built in, but es-lint is telling me it's not defined. Webstorm isn't helping me import it. Where do I import this from, or is there another issue here?
The code works:
} catch (error) {
console.log(error);
if (error instanceof GeolocationPositionError) {
console.log("Location access was denied");
return;
} else {
setTimeout(() => {
console.log("retrying");
dispatch(fetchUserLocation());
}, 2000);
}
}

I mocked it like this:
class GeolocationPositionError extends Error {
readonly code: number;
readonly message: string;
readonly PERMISSION_DENIED: number;
readonly POSITION_UNAVAILABLE: number;
readonly TIMEOUT: number;
constructor(msg?: string) {
super(msg);
}
}
global.GeolocationPositionError = GeolocationPositionError;
It's not a true "mock", but it allows jsdom to properly resolve the global. You can spy on it using jest.spyOn(global, "GeolocationPositionError")

Related

How to fix subscribe not exist in type void

I am new to angular 7 and didn't find any proper answer for similar questions posted.
I am getting Property 'subscribe' does not exist on type 'void' in angular-cli. I tried importing subscribe from rxjs but didn't find that library.
The problem is in the UpdateRecord Function!
product.component.ts code:
the code bellow is exist in compoent.ts of product
import { Component, OnInit } from '#angular/core';
import { ProductService } from 'src/app/shared/product.service';
import { NgForm } from '#angular/forms';
import { ToastrService } from 'ngx-toastr';
import { filter, map } from 'rxjs/operators';
#Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
constructor(private service : ProductService, private toastr : ToastrService) { }
ngOnInit() {
this.resetForm();
}
resetForm(form?: NgForm) {
if (form != null)
form.resetForm();
this.service.formData = {
ProductID: null,
ProductName: '',
ProductDescription: '',
Price: 0.00,
Image: '',
Qte: null
}
}
onSubmit(form: NgForm) {
if (form.value.ProductID == null)
this.insertRecord(form);
else
this.updateRecord(form);
}
insertRecord(form: NgForm) {
this.service.postProduct(form.value).subscribe(res => {
this.toastr.success('Inserted successfully', 'Product. Register');
this.resetForm(form);
this.service.refreshList();
});
}
updateRecord(form: NgForm) {
this.service.putProduct(form.value).subscribe(res => {
this.toastr.success('Updated successfully', 'Product. Update');
this.resetForm(form);
this.service.refreshList();
});
}
}
product.service.ts code :
the code bellow is exist in service file related to product
import { Injectable } from '#angular/core';
import { Product } from './product.model';
import { HttpClient } from "#angular/common/http";
#Injectable({
providedIn: 'root'
})
export class ProductService {
formData : Product
list : Product[]
readonly rootURL= 'http://localhost:50369/api'
constructor(private http : HttpClient) { }
postProduct(formData : Product){
return this.http.post(this.rootURL+'/Product', formData);
}
refreshList(){
return this.http.get(this.rootURL+'/Product')
.toPromise().then(res => this.list = res as Product[]);
}
putProduct(formData : Product){
this.http.put(this.rootURL+'/Product/'+formData.ProductID,FormData);
}
}
Thanks in advance,
I missed return :
So in putProduct function in product.service.ts is updated to be :
putProduct(formData : Product){
return this.http.put(this.rootURL+'/Product/'+formData.ProductID,FormData);
}
And it's working now!
Your HttpClient.put function seems to be incorrectly used (you are passing the class as parameter when you should be passing the object).
Look for the function updateHero() in this StackBlitz example.
/** PUT: update the hero on the server. Returns the updated hero upon success. */
updateHero (hero: Hero): Observable<Hero> {
httpOptions.headers =
httpOptions.headers.set('Authorization', 'my-new-auth-token');
return this.http.put<Hero>(this.heroesUrl, hero, httpOptions)
.pipe(
catchError(this.handleError('updateHero', hero))
);
}

How to handle TypeORM entity field unique validation error in NestJS?

I've set a custom unique validator decorator on my TypeORM entity field email. NestJS has dependency injection, but the service is not injected.
The error is:
TypeError: Cannot read property 'findByEmail' of undefined
Any help on implementing a custom email validator?
user.entity.ts:
#Column()
#Validate(CustomEmail, {
message: "Title is too short or long!"
})
#IsEmail()
email: string;
My CustomEmail validator is
import {ValidatorConstraint, ValidatorConstraintInterface,
ValidationArguments} from "class-validator";
import {UserService} from "./user.service";
#ValidatorConstraint({ name: "customText", async: true })
export class CustomEmail implements ValidatorConstraintInterface {
constructor(private userService: UserService) {}
async validate(text: string, args: ValidationArguments) {
const user = await this.userService.findByEmail(text);
return !user;
}
defaultMessage(args: ValidationArguments) {
return "Text ($value) is too short or too long!";
}
}
I know I could set unique in the Column options
#Column({
unique: true
})
but this throws a mysql error and the ExceptionsHandler that crashes my app, so I can't handle it myself...
Thankx!
I can propose 2 different approaches here, the first one catches the constraint violation error locally without additional request, and the second one uses a global error filter, catching such errors in the entire application. I personally use the latter.
Local no-db request solution
No need to make additional database request. You can catch the error violating the unique constraint and throw any HttpException you want to the client. In users.service.ts:
public create(newUser: Partial<UserEntity>): Promise<UserEntity> {
return this.usersRepository.save(newUser).catch((e) => {
if (/(email)[\s\S]+(already exists)/.test(e.detail)) {
throw new BadRequestException(
'Account with this email already exists.',
);
}
return e;
});
}
Which will return:
Global error filter solution
Or even create a global QueryErrorFilter:
#Catch(QueryFailedError)
export class QueryErrorFilter extends BaseExceptionFilter {
public catch(exception: any, host: ArgumentsHost): any {
const detail = exception.detail;
if (typeof detail === 'string' && detail.includes('already exists')) {
const messageStart = exception.table.split('_').join(' ') + ' with';
throw new BadRequestException(
exception.detail.replace('Key', messageStart),
);
}
return super.catch(exception, host);
}
}
Then in main.ts:
async function bootstrap() {
const app = await NestFactory.create(/**/);
/* ... */
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new QueryErrorFilter(httpAdapter));
/* ... */
await app.listen(3000);
}
bootstrap();
This will give generic $table entity with ($field)=($value) already exists. error message. Example:
I have modified my code. I am checking the uniqueness of username/email in the user service (instead of a custom validator) and return an HttpExcetion in case the user is already inserted in the DB.
The easiest solution!
#Entity()
export class MyEntity extends BaseEntity{
#Column({unique:true}) name:string;
}
export abstract class BaseDataService<T> {
constructor(protected readonly repo: Repository<T>) {}
private async isUnique(t: any) {
const uniqueColumns = this.repo.metadata.uniques.map(
(e) => e.givenColumnNames[0]
);
for (const u of uniqueColumns) {
const count = await this.repo.count({ where: { [u]: ILike(t[u]) } });
if (count > 0) {
throw new UnprocessableEntityException(`${u} must be unique!`);
}
}
}
async save(body: DeepPartial<T>) {
await this.isUnique(body);
try {
return await this.repo.save(body);
} catch (err) {
throw new UnprocessableEntityException(err.message);
}
}
async update(id: number, updated: QueryDeepPartialEntity<T>) {
await this.isUnique(updated)
try {
return await this.repo.update(id, updated);
} catch (err) {
throw new UnprocessableEntityException(err.message);
}
}
}
An approach that works for modern version of NestJS which is based in Daniel Kucal's answer and actually returns the error to the frontend when calling the JSON API is the following:
import {
Catch,
ArgumentsHost,
BadRequestException,
HttpException,
} from '#nestjs/common';
import { BaseExceptionFilter } from '#nestjs/core';
import { QueryFailedError } from 'typeorm';
type ExceptionType = { detail: string; table: string };
#Catch(QueryFailedError)
export class QueryErrorFilter extends BaseExceptionFilter<
HttpException | ExceptionType
> {
public catch(exception: ExceptionType, host: ArgumentsHost): void {
const { detail = null } = exception || {};
if (
!detail ||
typeof detail !== 'string' ||
// deepcode ignore AttrAccessOnNull: <False positive>
!detail.includes('already exists')
) {
return super.catch(exception, host);
} // else
/**
* this regex transform the message `(phone)=(123)` to a more intuitive `with phone: "123"` one,
* the regex is long to prevent mistakes if the value itself is ()=(), for example, (phone)=(()=())
*/
const extractMessageRegex =
/\((.*?)(?:(?:\)=\()(?!.*(\))(?!.*\))=\()(.*?)\)(?!.*\)))(?!.*(?:\)=\()(?!.*\)=\()((.*?)\))(?!.*\)))/;
const messageStart = `${exception.table.split('_').join(' ')} with`;
/** prevent Regex DoS, doesn't treat messages longer than 200 characters */
const exceptionDetail =
exception.detail.length <= 200
? exception.detail.replace(extractMessageRegex, 'with $1: "$3"')
: exception.detail;
super.catch(
new BadRequestException(exceptionDetail.replace('Key', messageStart)),
host,
);
}
}
Also, not forgetting main.ts:
async function bootstrap() {
const app = await NestFactory.create(/**/);
/* ... */
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new QueryErrorFilter(httpAdapter));
/* ... */
await app.listen(3000);
}
bootstrap();

Error: Can't resolve all parameters for CustomerService: (?)

Here i create two ts file one is service another is General in service i implement some service and calling in General ts file while my page getting load its throughing Error as at NoProviderError.BaseError [as constructor]
Service.ts
#Component({
templateUrl: "../../template/customer/customer.html",
providers: [CustomerService]
})
Url = "http://localhost:54873/Api/Home/GetEmp"
public constructor(private _http: Http) {
}
getEmpData() {
debugger;
return this._http.get(this.Url).map(this.extractData).catch(this.handleError);
}
Component.ts
#Component({
templateUrl: "../../template/customer/customer.html",
providers: [CustomerService]
})
#Injectable()
export class CustomerComponent {
Url = "http://localhost:54873/Api/Home/GetEmp"
getfun: string;
constructor(private _HttpService: CustomerService) { }
getData() {
return this._HttpService.getEmpData().subscribe(data => this.getfun = JSON.stringify(data), error => alert('This is error...'),
() => console.log());
}
You cannot have #Component inside a service.ts file, it should be as follows,
#Injectable()
export class CustomerService {
public constructor(private _http: Http) {
}
getEmpData(): Observable<Employee[]> {
debugger;
return this._http.get(this.Url).map(this.extractData).catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
// this.Employees = res.json
return body.data || {};
}
private handleError(error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}

Unable to get single property from response Angular 2

I want to access the property 'Status' from the controller and simply do some operations but I am unable to get this property and do any further operation. I am sharing my code below:
TasksController:
[HttpGet]
public ActionResult GetTasks()
{
var q = (from a in db.Tsk
join b in db.TType on a.TaskTypeID equals b.TaskTypeID
join c in db.Prior on a.PriorityID equals c.PriorityID
join d in db.Usr on a.AssignedTo equals d.Employees.EmpName
select new
{
a.TaskID,
a.TaskCode,
a.AssignedTo,
a.Date,
a.DueDate,
a.Status,
a.Reply,
a.PriorityID,
a.TaskTypeID,
b.TaskType,
c.Priorities,
d.Login
}).ToList().Skip(1).AsEnumerable();
db.Configuration.ProxyCreationEnabled = false;
return Json(q, JsonRequestBehavior.AllowGet);
}
AppService:
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
import { Observable } from 'rxjs/Observable'
#Injectable()
export class AppService {
constructor(private _http: Http) { }
//Task Register
getFTRs(c: string) {
return this._http.get('Tasks/GetTasks').map(res => res.json().filter(a => a.Login === c));
}
}
HomeComponent:
import { Component, OnInit, Input } from '#angular/core';
import { AuthenticationService } from '../_services/index';
import { AppService } from '../app.service';
import { LoginComponent } from '../login/index';
import { User, TaskRegisters } from '../contract';
import { Message } from '../message';
#Component({
moduleId: module.id,
selector: 'home',
templateUrl: 'home.component.html',
providers: [LoginComponent]
})
export class HomeComponent implements OnInit {
users: User[];
tasks: string;
msgs: Message[] = [];
curr: any;
constructor(private userService: AuthenticationService,
private Tsk: AppService,
private Log: LoginComponent) { }
ngOnInit() {
debugger;
this.curr = localStorage.getItem('currentUser').slice(1);
this.Tsk.getFTRs(this.curr).subscribe(
res => {
this.tasks = res.Status,
error => console.log(error)
});
if (this.tasks) {
this.msgs.push({ severity: 'error', summary: 'Task Assigned', detail: 'A new task has been assigned to you' })
}
}
}
Status is a boolean and if boolean is true, I want to push the message in msgs array. I am unable to get the value of Status and store it in tasks variable of home component. Whenever I run the program it shows this.tasks as undefined thus making and comparison impossible. Any help will be appreciated.
Change:
this.Tsk.getFTRs(this.curr).subscribe(
res => {
this.tasks = res.Status,
error => console.log(error)
});
if (this.tasks) {
this.msgs.push({ severity: 'error', summary: 'Task Assigned', detail: 'A new task has been assigned to you' })
}
to
this.Tsk.getFTRs(this.curr).subscribe(
(res) => {
console.log(res); //What does this print?
this.tasks = res.Status;
console.log(this.tasks); //What does this print?
if (this.tasks) {
this.msgs.push({ severity: 'error', summary: 'Task Assigned', detail: 'A new task has been assigned to you' })
}
},
(error) => {console.log(error);}
);
Since you're assingning this.tasks inside getFRSs' callback which is async, by the time you are using it below in the if statement it is undefined.
Since this.tasks is available to me now after the edit of #echonax I did this to make it work!
ngOnInit() {
debugger;
this.curr = localStorage.getItem('currentUser').slice(1);
this.Tsk.getFTRs(this.curr).subscribe(
res => {
this.tasks = res;
for (let i = 0; i < this.tasks.length; i++){
if (this.tasks[i].Status) {
this.msgs.push({ severity: 'error', summary: 'Task Assigned', detail: 'A new task has been assigned to you' })
}
}
},
error => console.log(error)
)}

custom annotation / Metadata in dart lang

Can any one explain me the use of annotations in Dart?
In the documentations, I found this example:
library todo;
class todo {
final String who;
final String what;
const todo(this.who, this.what);
}
followed by
import 'todo.dart';
#todo('seth', 'make this do something')
void doSomething() {
print('do something');
}
so, what shall I write in the main() to get the doSomething() function executed?
thanks
Something like
import 'dart:mirrors';
import 'do_something.dart';
import 'todo.dart';
void main() {
currentMirrorSystem().libraries.forEach((uri, lib) {
//print('lib: ${uri}');
lib.declarations.forEach((s, decl) {
//print('decl: ${s}');
decl.metadata.where((m) => m.reflectee is Todo).forEach((m) {
var anno = m.reflectee as Todo;
if(decl is MethodMirror) {
print('Todo(${anno.who}, ${anno.what})');
((decl as MethodMirror).owner as LibraryMirror).invoke(s, []);
};
});
});
});
}

Resources