I'm trying to use SecureStorage in ionic-native
let secureStorage: SecureStorage = new SecureStorage();
secureStorage.create('my_store_name')
.then(
() => console.log('Storage is ready!'),
error => console.log(error)
);
but I'm getting the error "undefined is not a constructor (evaluating 'new cordova.plugins.SecureStorage(res, rej, store)')" on iphone 5s
Any idea?
I have this code in a provider and it works for me...:
...
public virtual: boolean = true;
public ss: SecureStorage;
constructor(
private _http: Http,
private _config: ConfigurationService,
private _events: Events) {
this.virtual = Device.device.isVirtual;
if (this.virtual !== undefined && !this.virtual) {
console.log(`Using SecureStorage`);
this.ss = new SecureStorage();
this.ss.create('ss')
.then(
() => {
this.virtual = false;
this._events.publish('StorageReady');
},
error => console.log(error)
);
} else {
console.log(`Using localstorage for simulation`);
this.virtual = true;
}
} ....
Hope it helps...
Related
PeerJS: 1.3.2
Tested on: iOS 15 & 13.
I have the below call service file that implements PeerJS functionality to init, establish and answer video calls.
Calls work as expected across Android devices, macOS and PCs.
However, when attempting to join from an iOS device, we see the following error raised:
NotAllowedError: The request is not allowed by the user agent
or the platform in the current context, possibly because the
user denied permission.
call-service.js:
import { Injectable } from '#angular/core';
import { MatSnackBar } from '#angular/material/snack-bar';
import Peer from 'peerjs';
import { BehaviorSubject, Subject } from 'rxjs';
import { v4 as uuidv4 } from 'uuid';
#Injectable()
export class CallService {
private peer: Peer;
private mediaCall: Peer.MediaConnection;
private localStreamBs: BehaviorSubject<MediaStream> = new BehaviorSubject(null);
public localStream$ = this.localStreamBs.asObservable();
private remoteStreamBs: BehaviorSubject<MediaStream> = new BehaviorSubject(null);
public remoteStream$ = this.remoteStreamBs.asObservable();
private isCallStartedBs = new Subject<boolean>();
public isCallStarted$ = this.isCallStartedBs.asObservable();
constructor(private snackBar: MatSnackBar) { }
public initPeer(): string {
if (!this.peer || this.peer.disconnected) {
const peerJsOptions: Peer.PeerJSOption = {
debug: 3,
config: {
iceServers: [
{
urls: [
'stun:stun1.l.google.com:19302',
'stun:stun2.l.google.com:19302',
],
}]
}
};
try {
let id = uuidv4();
this.peer = new Peer(id, peerJsOptions);
return id;
} catch (error) {
console.error(error);
}
}
}
public async establishMediaCall(remotePeerId: string) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true});
let peerOptions: any = {};
if (this.checkSafari()) {
peerOptions.serialization = "json";
}
const connection = this.peer.connect(remotePeerId, peerOptions);
connection.on('error', err => {
console.error(err);
this.snackBar.open(err, 'Close');
});
this.mediaCall = this.peer.call(remotePeerId, stream);
if (!this.mediaCall) {
let errorMessage = 'Unable to connect to remote peer';
this.snackBar.open(errorMessage, 'Close');
throw new Error(errorMessage);
}
this.localStreamBs.next(stream);
this.isCallStartedBs.next(true);
this.mediaCall.on('stream',
(remoteStream) => {
this.remoteStreamBs.next(remoteStream);
});
this.mediaCall.on('error', err => {
this.snackBar.open(err, 'Close');
console.error(err);
this.isCallStartedBs.next(false);
});
this.mediaCall.on('close', () => this.onCallClose());
}
catch (ex) {
console.error(ex);
this.snackBar.open(ex, 'Close');
this.isCallStartedBs.next(false);
}
}
public async enableCallAnswer() {
try {
let peerOptions: any = {};
if (this.checkSafari()) {
peerOptions.serialization = "json";
}
const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
this.localStreamBs.next(stream);
this.peer.on('call', async (call) => {
this.mediaCall = call;
this.isCallStartedBs.next(true);
this.mediaCall.answer(stream);
this.mediaCall.on('stream', (remoteStream) => {
this.remoteStreamBs.next(remoteStream);
});
this.mediaCall.on('error', err => {
this.snackBar.open(err, 'Close');
this.isCallStartedBs.next(false);
console.error(err);
});
this.mediaCall.on('close', () => this.onCallClose());
});
}
catch (ex) {
console.error(ex);
this.snackBar.open(ex, 'Close');
this.isCallStartedBs.next(false);
}
}
private onCallClose() {
this.remoteStreamBs?.value.getTracks().forEach(track => {
track.stop();
});
this.localStreamBs?.value.getTracks().forEach(track => {
track.stop();
});
this.snackBar.open('Call Ended', 'Close');
}
public closeMediaCall() {
this.mediaCall?.close();
if (!this.mediaCall) {
this.onCallClose()
}
this.isCallStartedBs.next(false);
}
public destroyPeer() {
this.mediaCall?.close();
this.peer?.disconnect();
this.peer?.destroy();
}
public checkSafari() {
let seemsChrome = navigator.userAgent.indexOf("Chrome") > -1;
let seemsSafari = navigator.userAgent.indexOf("Safari") > -1;
return seemsSafari && !seemsChrome;
}
}
Closing. This was a local permissions issue on my test device and no fault of PeerJS.
Reinstalling Chrome on iOS then enabled the relevant camera permissions
Currently I'm learning Flutter and I have an error during the execution of a project that I can't find. Maybe someone has an idea where the error could be?
This is the error:
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
This is the function in which the error is located:
Future<void> fetchAndSetProducts([bool filterByUser = false]) async {
final filterString = filterByUser ? 'orderBy="creatorId"&equalTo="$userId"' : '';
var url =
'https://xxxx.firebaseio.com/products.json?auth=$authToken&$filterString';
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
if (extractedData == null) {
return;
}
url =
'https://xxxx.firebaseio.com/userFavorites/$userId.json?auth=$authToken';
final favoriteResponse = await http.get(url);
final favoriteData = json.decode(favoriteResponse.body);
final List<Product> loadedProducts = [];
extractedData.forEach((prodId, prodData) {
loadedProducts.add(Product(
id: prodId,
title: prodData['title'],
description: prodData['description'],
price: prodData['price'],
isFavorite:
favoriteData == null ? false : favoriteData[prodId] ?? false,
imageUrl: prodData['imageUrl'],
));
});
_items = loadedProducts;
notifyListeners();
} catch (error) {
throw (error);
}
}
I am new to Asp.net MVC Core. I am working on Server-side loading of JQuery Datatables.net using Asp.Net Core MVC Middleware.
I have used this tutorial to learn how to create a handler and then this article to migrate to middleware but are running into some issues that I hope you can help me with.
I have refined using this tutorial
I get error
"InvalidOperationException: Incorrect Content-Type: Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm()"
when I run the solution.
Here is my code:
View
<script type="text/javascript">
$(document).ready(function () {
$('#datatable').DataTable({
//"paging": true,
//"ordering": true,
//"info": true,
'columns' : [
{ 'data': 'InsertedDateUtc' },
//{ 'data': 'EventId' },
{ 'data': 'UserId' },
{ 'data': 'Action' },
{ 'data': 'Context' },
{ 'data': 'RecordId' },
{ 'data': 'Property' },
{ 'data': 'OldValue' },
{ 'data': 'NewValue' },
],
'processing': true,
'serverSide': true,
'ajax' : {
'type' : 'POST',
'url' : '../AuditEventData.cs',
//'url': '../APIController/GetAuditEvents'
//'url' : '#Url.Action("GetAuditEvents", "APIController")'
'datatype': 'json',
}
});
});
</script>
Middleware
public class AuditEventData
{
private readonly RequestDelegate _next;
private readonly IDataGet _dataGet;
public AuditEventData(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
string result = null;
int filteredCount = 0;
var draw = httpContext.Request.Form["draw"].FirstOrDefault();
var start = int.Parse(httpContext.Request.Form["start"].FirstOrDefault());
var length = int.Parse(httpContext.Request.Form["length"].FirstOrDefault());
var sortCol = int.Parse(httpContext.Request.Form["columns[" + httpContext.Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault());
var sortDir = httpContext.Request.Form["order[0][dir]"].FirstOrDefault();
var search = httpContext.Request.Form["search[value]"].FirstOrDefault();
try
{
var auditEvents = await _dataGet.GetServerSideAuditEvents(length, start, sortCol, sortDir, search);
filteredCount = auditEvents.Count();
var data = new
{
iTotalRecords = await _dataGet.GetTotalAuditEventCount(),
iTotalDisplayRecords = filteredCount,
aaData = auditEvents
};
result = JsonConvert.SerializeObject(data);
await httpContext.Response.WriteAsync(result);
}
catch (Exception e)
{
await ErrorHandler.HandleException(e);
}
await _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseAuditEventDataMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuditEventData>();
}
}
Startup.cs
app.MapWhen(
context => context.Request.Path.ToString().EndsWith("ViewAudit"),
appBranch =>
{
appBranch.UseAuditEventDataMiddleware();
});
In the middleware class the line
var start = int.Parse(httpContext.Request.Form["start"].FirstOrDefault());
gives me the error - the tutorials and Microsoft documentation here seem to indicate that I do not need to use the ".Form" and should be able to just use
var start = int.Parse(httpContext.Request["start"].FirstOrDefault());
however, when I do that, I get this error
cannot apply indexing with [] to an expression of type 'HttpRequest'
I cannot find any examples on how to do this and any help will be appreciated
Thanks
In order to expect to have a Form in your HttpContext.Request you must change your ajax datatype to 'application/x-www-form-urlencoded'. Now whether you want to do that is another question.
From here: https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data
I am migrating a Laravel app to Node app using TypeORM. Has anyone been able to implement something similar to Laravel's Polymorphic Relations in TypeOrm?
Example schema I am trying to reproduce:
export class Notification {
id: string;
attachable_id: number;
attachable_type: string;
}
I want to be able to to have a notification.attachable relation that could be of any type. Then, ideally, I can eager load a user with their last x notifications, with the attachable on each notification.
EDIT:
So I done a refactor/rewrite and put it all in a repo https://github.com/bashleigh/typeorm-polymorphic
So, I've been thinking of trying to implement something for this for a while. I had 2 days to implement something in a hurry so I made this crud thing.
import {
FindManyOptions,
DeepPartial,
ObjectID,
FindConditions,
UpdateResult,
Repository,
SaveOptions,
} from 'typeorm';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
export interface PolymorphicInterface {
entityId: string;
entityType: string;
}
export type PolyMorphicType<K> = PolymorphicInterface & DeepPartial<K>;
export const POLYMORPHIC_RELATIONSHIP = 'POLYMORPHIC_RELATIONSHIP';
export interface PolymorphicOptions {
type: Function;
parent: Function;
property: string | Symbol;
}
export const PolyMorphic = (type: Function): PropertyDecorator => (
target: Object,
propertyKey: string | Symbol,
): void =>
Reflect.defineMetadata(
`${POLYMORPHIC_RELATIONSHIP}::${propertyKey}`,
{
type,
parent: target.constructor.name,
property: propertyKey,
},
target,
);
export class PolymorphicRepository<T extends DeepPartial<T>> extends Repository<T> {
private getMetadata(): Array<PolymorphicOptions> {
let keys = Reflect.getMetadataKeys((this.metadata.target as Function)['prototype']);
if (!Array.isArray(keys)) {
return [];
}
keys = keys.filter((key: string) => {
const parts = key.split('::');
return parts[0] === POLYMORPHIC_RELATIONSHIP;
});
if (!keys) {
return [];
}
return keys.map(
(key: string): PolymorphicOptions =>
Reflect.getMetadata(key, (this.metadata.target as Function)['prototype']),
);
}
async find(findOptions?: FindConditions<T> | FindManyOptions<T>): Promise<T[]> {
const polymorphicMetadata = this.getMetadata();
if (Object.keys(polymorphicMetadata).length === 0) {
return super.find(findOptions);
}
const entities = await super.find(findOptions);
return this.hydratePolymorphicEntities(entities);
}
public async hydratePolymorphicEntities(entities: Array<T>): Promise<Array<T>> {
const metadata = this.getMetadata();
metadata.forEach(
async (data: PolymorphicOptions): Promise<void> => {
await Promise.all(
entities.map(
async (entity: T): Promise<void> => {
const repository = this.manager.getRepository(data.type);
const property = data.property;
const parent = data.parent;
if (!repository) {
throw new Error(
`Repository not found for type [${
data.type
}] using property [${property}] on parent entity [${parent}]`,
);
}
const morphValues = await repository.find({
where: {
//#ts-ignore
entityId: entity.id, // TODO add type AbstractEntity
entityType: this.metadata.targetName,
},
});
//#ts-ignore
entity[property] = morphValues;
},
),
);
},
);
return entities;
}
public async update(
criteria:
| string
| string[]
| number
| number[]
| Date
| Date[]
| ObjectID
| ObjectID[]
| FindConditions<T>,
partialEntity: QueryDeepPartialEntity<T>,
): Promise<UpdateResult> {
const polymorphicMetadata = this.getMetadata();
if (Object.keys(polymorphicMetadata).length === 0) {
return super.update(criteria, partialEntity);
}
const result = super.update(criteria, partialEntity);
// TODO update morphs
throw new Error("CBA I'm very tired");
return result;
}
public async save<E extends DeepPartial<T>>(
entity: E | Array<E>,
options?: SaveOptions & { reload: false },
): Promise<E & T | Array<E & T>> {
const polymorphicMetadata = this.getMetadata();
if (Object.keys(polymorphicMetadata).length === 0) {
return Array.isArray(entity) ? super.save(entity, options) : super.save(entity);
}
const result = Array.isArray(entity)
? await super.save(entity, options)
: await super.save(entity);
Array.isArray(result)
? await Promise.all(result.map((res: T) => this.saveMorphs(res)))
: await this.saveMorphs(result);
return result;
}
private async saveMorphs(entity: T): Promise<void> {
const metadata = this.getMetadata();
await Promise.all(
metadata.map(
async (data: PolymorphicOptions): Promise<void> => {
const repository: Repository<PolymorphicInterface> = this.manager.getRepository(
data.type,
);
const property = data.property;
const parent = data.parent;
const value: Partial<PolymorphicInterface> | Array<Partial<PolymorphicInterface>> =
//#ts-ignore
entity[property];
if (typeof value === 'undefined' || value === undefined) {
return new Promise(resolve => resolve());
}
if (!repository) {
throw new Error(
`Repository not found for type [${
data.type
}] using property [${property}] on parent entity [${parent}]`,
);
}
let result: Array<any> | any;
if (Array.isArray(value)) {
//#ts-ignore
result = await Promise.all(
value.map(val => {
// #ts-ignore
val.entityId = entity.id;
val.entityType = this.metadata.targetName;
return repository.save(
value instanceof data.type ? value : repository.create(value),
);
}),
);
} else {
// #ts-ignore
value.entityId = entity.id; // TODO resolve AbstractEntity for T
value.entityType = this.metadata.targetName;
result = await repository.save(
value instanceof data.type ? value : repository.create(value),
);
}
// #ts-ignore
entity[property] = result;
},
),
);
}
}
It's pretty rough but that's what I implemented to tackle this. Essentially I've implemented is my own methods to handle saving of entities that are defined within the metadata by creating my own repository.
Then you can use it like so
#Entity()
export class TestEntity {
#PolyMorphic(SomeOtherEntity)
property: SomeOtherEntity[];
}
The typings are really bad but that's only because I've had 1 days to implement this feature and I did it on the plane
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);
}
}