I am using ionic2 storage a below:
//page2.ts
import { Storage } from '#ionic/storage';
export class LoginPage {
...
//this works fine
onLogin(){
this.storage.set('uid', '12345');
}
}
//page2.ts
export class Foo {
//no value gets retrieved here
onSave() {
this.storage.get('uid')
.then(uid => console.log(uid));
}
}
No value gets retrieved and no error is thrown, what am i missing ?
Try using NativeStorage. It is one of native-ionic plugins and it won't be deleted unless you programmatically delete it or user deletes an app. With NativeStorage you would do.
NativeStorage.setItem('uid',{value: this.uid}.then(()=>{
console.log("uid is saved);
})
NativeStorage.getItem('uid').then((data)=>{
console.log("uid value is: " + data.value);
})
Related
I have two databases that I need to interact with in my code. I have a simple function that takes an object and writes it to my PostgreSQL database using Prisma. I've tested the function with Postman, and it works perfectly, but when I try to execute it using a Jest mock (using the singleton pattern found in the Prisma unit testing guide), it returns undefined indicating that it didn't interact with the database and create the new record. Here's my code:
/prisma/clinical-schema.prisma
generator client {
provider = "prisma-client-js"
output = "./generated/clinical"
}
datasource clinicalDatabase {
provider = "postgresql"
url = "postgresql://postgres:postgres#localhost:5432/clinical-data?schema=public"
}
model pcc_webhook_update {
id Int #id #default(autoincrement())
event_type String
organization_id Int
facility_id Int
patient_id Int
resource_id String?
webhook_date DateTime #default(now()) #clinicalDatabase.Timestamptz(6)
status pcc_webhook_update_status #default(pending)
status_changed_date DateTime? #clinicalDatabase.Timestamptz(6)
error_count Int #default(0)
##unique([organization_id, facility_id, patient_id, resource_id, event_type, status])
}
enum pcc_webhook_update_status {
pending
processing
processed
error
}
/prisma/clinical-client.ts
import { PrismaClient } from './generated/clinical';
const prismaClinical = new PrismaClient();
export default prismaClinical;
/testing/prisma-clinical-mock.ts
import { PrismaClient } from '../prisma/generated/clinical';
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended';
import prisma from '../prisma/clinical-client';
jest.mock('../prisma/clinical-client', () => ({
__esModule: true,
default: mockDeep<PrismaClient>()
}));
beforeEach(() => {
mockReset(prismaClinicalMock);
});
export const prismaClinicalMock = prisma as unknown as DeepMockProxy<PrismaClient>;
Everything up to this point follows the conventions outlined by the Prisma unit testing docs. The only modification I made was to make it database specific. Below is my function and tests. The request object in handle-pcc-webhooks.ts is a sample http request object, the body of which contains the webhook data I care about.
/functions/handle-pcc-webhooks/handler.ts
import prismaClinical from '../../../prisma/clinical-client';
import { pcc_webhook_update } from '../../../prisma/generated/clinical';
import { requestObject } from './handler.types';
export const handlePccWebhook = async (request: requestObject) => {
try {
const webhook = JSON.parse(request.body);
// if the webhook doesn't include a resource id array, set it to an array with an empty string to ensure processing and avoid violating
// the multi-column unique constraint on the table
const { resourceId: resourceIds = [''] } = webhook;
let records = [];
for (const resourceId of resourceIds) {
// update an existing record if one exists in the pending state, otherwise create a new entry
const record: pcc_webhook_update = await prismaClinical.pcc_webhook_update.upsert({
where: {
organization_id_facility_id_patient_id_resource_id_event_type_status: {
organization_id: webhook.orgId,
facility_id: webhook.facId,
patient_id: webhook.patientId,
resource_id: resourceId,
event_type: webhook.eventType,
status: 'pending'
}
},
update: {
webhook_date: new Date()
},
create: {
event_type: webhook.eventType,
organization_id: webhook.orgId,
facility_id: webhook.facId,
patient_id: webhook.patientId,
resource_id: resourceId,
status: 'pending' // not needed
}
});
records.push(record);
}
return records;
} catch (error) {
console.error(error);
}
};
/functions/handle-pcc-webhooks/handler.spec.ts
import fs from 'fs';
import path from 'path';
import MockDate from 'mockdate';
import { prismaClinicalMock } from '../../../testing/prisma-clinical-mock';
import { createAllergyAddRecord } from './__mocks__/allergy';
import { requestObject } from './handler.types';
import { handlePccWebhook } from './handler';
describe('allergy.add', () => {
let requestObject: requestObject;
let allergyAddRecord: any;
beforeAll(() => {
requestObject = getRequestObject('allergy.add');
});
beforeEach(() => {
MockDate.set(new Date('1/1/2022'));
allergyAddRecord = createAllergyAddRecord(new Date());
});
afterEach(() => {
MockDate.reset();
});
test('should create an allergy.add database entry', async() => {
prismaClinicalMock.pcc_webhook_update.create.mockResolvedValue(allergyAddRecord);
// this is where I would expect handlePccWebhook to return the newly created database
// record, but instead it returns undefined. If I run the function outside of this
// unit test, with the same input value, it functions perfectly
await expect(handlePccWebhook(requestObject)).resolves.toEqual([allergyAddRecord]);
});
});
// This just builds a request object with the current webhook being tested
function getRequestObject(webhookType: string) {
// read the contents of request object file as a buffer, then convert it to JSON
const rawRequestObject = fs.readFileSync(path.resolve(__dirname, '../../sample-data/handle-pcc-webhook-request.json'));
const requestObject: requestObject = JSON.parse(rawRequestObject.toString());
// read the contents of the webhook file as a buffer, then convert it to a string
const rawWebhook = fs.readFileSync(path.resolve(__dirname, `../../sample-data/${webhookType}.json`));
const webhookString = rawWebhook.toString();
// set the body of the request object to the contents of the target webhook
requestObject.body = webhookString;
return requestObject;
}
Finally, here is the result of running the unit test:
So after banging my had against the wall for a few hours, I figured out the issue. In my handler.spec.ts file, I had the following line:
prismaClinicalMock.pcc_webhook_update.create.mockResolvedValue(allergyAddRecord);
what that does is mock the value returned for any create functions run using Prisma. The issue is that my function is using an upsert function, which I wasn't explicitly mocking, thus returning undefined. I changed the above line to
prismaClinicalMock.pcc_webhook_update.upsert.mockResolvedValue(allergyAddRecord);
and it started working.
As described here, I have implemented the authorization:
start/bouncer.ts:
import Bouncer from '#ioc:Adonis/Addons/Bouncer'
export const { actions } = Bouncer
export const { policies } = Bouncer.registerPolicies({
UserPolicy: () => import('App/Policies/UserPolicy'),
})
app/Policies/UserPolicy.ts:
import { BasePolicy } from '#ioc:Adonis/Addons/Bouncer'
import User from 'App/Models/User'
export default class UserPolicy extends BasePolicy {
public async before(user?: User) {
return user?.isSuperUser
}
public async list(user: User) {
await user.load('policies')
return user.policies.some((policy) => policy.identifier === 'user:list')
}
// ...
}
resources/vires/layouts/main.edge
#can('UserPolicy.list')
<p>Can see users list</p>
#endcan
And I cannot see the paragraph. In fact, I placed console.log inside the action, but it didn't get executed. I don't know if I'm missing anything. Can anyone shed some lights onto it?
Gotcha! This says:
The actual action callback is never executed when a before hook returns a true or a false value.
Make sure to return undefined if you want the bouncer to execute the next hook or the action callback.
These 2 statements were missed out. :)
I'm trying to use ionic native's media plugin like this:
record(){
...
return this.media.create(src,onStatusUpdate).then((mediaObj) => {
mediaObj.startRecord();
return mediaObj;
});
}
And I use the mediaObj returned from it elsewhere, but I also need to know the status of the mediaObj; this apparently comes from passing a second argument, a callback function, to the media.create() function. However, I don't know how to get the mediaObj's status in there. I know the following would work for just telling me the status, but I actually need to access it.
const onStatusUpdate = (status) => console.log(status);
So, the question is, is there a way to simply access the mediaObj's status?
The MediaPlugin status update notification is all you get so set a class property with the value you get when the status change.
To manage the MediaObject I set a property to the value obtained when the promise is resolved.
import { ApplicationRef } from '#angular/core';
...
...
export class PlayerPage {
track:any;
file:MediaObject = undefined;
position:any = undefined;
status:any = 0;
constructor(public ref ApplicationRef, public navCtrl: NavController, private navParams: NavParams, public AppstateProvider: Appstate, private media: MediaPlugin) {
this.track = navParams.get('track');
media.create('http://.../...mp3',(status)=>{
this.status = status;
this.ref.tick();
}).then((file: MediaObject) => {
this.file = file;
});
}
play() {
this.file.play();
}
The this.ref.tick(); is necesarry because Angular does not detect this property update - I tried publishing and subscribing Angular still did not detect the property update.
AMQJS0005E Internal error. Error Message: Cannot read property 'subscribe' of undefined
I included eclipse paho javascript client library in my app.
connection is established but, I cannot subscribe to a topic.
here is the code that I used..
import { Component } from '#angular/core';
import { NavController, NavParams ,MenuController } from 'ionic-angular';
import { Setuser } from '../../providers/setuser';
import { Platform } from 'ionic-angular';
import { Paho} from 'ng2-mqtt/mqttws31';
/*
Generated class for the Usershome page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-usershome',
templateUrl: 'usershome.html'
})
export class UsershomePage {
client :any;
message :any;
constructor(public navCtrl: NavController, public navParams: NavParams,public menu:MenuController,public setUserProvider: Setuser,public platform:Platform) {
this.menu.open();
}
ionViewDidLoad() {
this.menu.enable(true);
console.log('ionViewDidLoad UsershomePage');
}
exitApp(){
console.log("----------");
this.platform.exitApp();
}
connectToMqtt(){
this.client = new Paho.MQTT.Client("test.mosquitto.org",8080,"abc");
// set callback handlers
this.client.onConnectionLost = this.onConnectionLost;
this.client.onMessageArrived = this.onMessageArrived;
// connect the client
this.client.connect({onSuccess:this.onConnect});
}
// called when the client connects
onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
this.client.subscribe("mitsuruog");
this.message = new Paho.MQTT.Message("Hello");
this.message.destinationName = "World";
this.client.send(this.message);
}
// called when the client loses its connection
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
// called when a message arrives
onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
}
Your immediate problem is solvable by modifying the line
this.client.connect({onSuccess:this.onConnect.bind(this)});
or, surprisingly for you, by removing all this. in front of client and message references.
You should learn what exactly means this in JavaScript. Not the same thing as in Java or C#. To understand why the removal works, learn about closures and arrow functions.
Good starting point (your question could be actually flagged as duplicate of this one):
How to access the correct `this` context inside a callback?
I do not understand why the object is not removed from the array? I tried to implement this solution Ember.js how to remove object from array controller without ember data but, the object is not removed from the previousParent.
changeCauseLinkParentRt(newParent, causeLink) {
if(!newParent) {
causeLink.get("parent").then(previousParent => {
previousParent.get("children").then(children =>{
var _newParent = children.findBy("order", causeLink.get("order")-1);
if(!!_newParent) {
var objRemove = null;
previousParent.get("children").then(children => {
objRemove = children.findBy("id", causeLink.get("id"));
children.removeObject(objRemove);
children.save();
causeLink.set("parent", _newParent);
causeLink.save();
_newParent.get("children").pushObject(causeLink);
_newParent.save();
});
}
});
})
} else {
//...
}
}
I found that Ember-Data (or the Firebase adapter) is returning a duplicate of the same record in some cisconstances. So removeObject() was deleting once instance the of the duplicate the record with the final result that the remaining other version was persisted back to the backend.