ionic run code to create databse only once - ionic-framework

I created an app using ionic, and in the app I want to create and populate a database, but I want the code to run once, not everytime I open the app. Because once the databace is create for first time, no need to run recreate it again.
I googled it, I did not find an answer,
I appreciate any one has a solution.
private dboptions: any = {
name: 'ba.db',
createFromLocation: 1,
location: 'default'
}
constructor(
private sqlite: SQLite) {
this.connectDB();
}
private connectDB(): any {
this.sqlite.create(this.dboptions).then(
(db: SQLiteObject) => {
// create the table
let sql = `CREATE TABLE ba (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR (200) NOT NULL UNIQUE,
title VARCHAR (200)`;
db.executeSql(sql, []).then(success => {
console.log('table created');
}).catch(err => {
console.log(err);
})
}
)
.catch(err => console.log(err));
}

User LocalStorage to check if DB is already created like this. Storage Here is the link on how to add local storage to your project.
private dboptions: any = {
name: 'ba.db',
createFromLocation: 1,
location: 'default'
}
constructor(
private sqlite: SQLite, , public storage: Storage) {
this.storage.get("isDbPresent")
.then((data) => {
console.log(data);
if (data === null) {
this.connectDB();
this.storage.get(Constants.storagekey)
}
})
}
private connectDB(): any {
this.sqlite.create(this.dboptions).then(
(db: SQLiteObject) => {
// create the table
let sql = `CREATE TABLE ba (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR (200) NOT NULL UNIQUE,
title VARCHAR (200)`;
db.executeSql(sql, []).then(success => {
console.log('table created');
}).catch(err => {
console.log(err);
})
}
)
.catch(err => console.log(err));
}

add ionic Storage and save a flag when done.
in app.module.ts
import { IonicStorageModule } from '#ionic/storage';
...
imports: [
...
IonicStorageModule.forRoot()
],
...
in your component/provider
import { Storage } from '#ionic/storage';
storage.ready().then(() => {
storage.get('notFirstTime').then((notFirstTime:boolean) => {
if (!notFirstTime){
// Do what you want to do once
}
storage.set('notFirstTime', true);
})
});
...
ionic storage is persistent (when you install cordova-sqlite-storageplugin)

Related

Prisma: how to delete a record where it may or may not have children

I am trying to figure out how to delete a record created in my graphql, apollo, prisma app, where the record I am deleting may have a has many relationship to another model.
I have a model called IssueGroups. IssueGroups have many issues.
I have a model with:
import * as Prisma from "#prisma/client"
import { Field, ObjectType } from "type-graphql"
import { BaseModel } from "../shared/base.model"
#ObjectType()
export class IssueGroup extends BaseModel implements Prisma.IssueGroup {
#Field()
title: string
#Field()
description: string
#Field(type => String)
issues: Prisma.Issue[];
}
A resolver with:
import { Arg, Mutation, Query, Resolver } from "type-graphql"
import { IssueGroup } from "./issueGroup.model"
import { IssueGroupService } from "./issueGroup.service"
import { IssueGroupInput } from "./inputs/create.input"
import { Inject, Service } from "typedi"
#Service()
#Resolver(() => IssueGroup)
export default class IssueGroupResolver {
#Inject(() => IssueGroupService)
issueGroupService: IssueGroupService
#Query(() => [IssueGroup])
async allIssueGroups() {
return await this.issueGroupService.getAllIssueGroups()
}
#Query(() => IssueGroup)
async issueGroup(#Arg("id") id: string) {
return await this.issueGroupService.getIssueGroup(id)
}
#Mutation(() => IssueGroup)
async createIssueGroup(#Arg("data") data: IssueGroupInput) {
return await this.issueGroupService.createIssueGroup(data)
}
// : Promise<IssueGroup[]> {
#Mutation(() => IssueGroup)
async updateIssueGroup(
#Arg("id") id: string,
#Arg("data") data: IssueGroupInput
) {
return await this.issueGroupService.updateIssueGroup(id, data)
}
#Mutation(() => IssueGroup)
async deleteIssueGroup(#Arg("id") id: string) {
return await this.issueGroupService.deleteIssueGroup(id)
}
}
// private readonly issueGroupService: IssueGroupService
// #Query(() => [IssueGroup])
// async issueGroups(): Promise<IssueGroup[]> {
// return this.issueGroupService.findAll()
// }
// #Query(() => IssueGroup)
// async issueGroup(#Arg("id") id: string): Promise<IssueGroup> {
// return this.issueGroupService.findOne(id)
// }
// #Mutation(() => IssueGroup)
// async createIssueGroup(
// #Arg("data") data: IssueGroupInput
// ): Promise<IssueGroup> {
// return this.issueGroupService.create(data)
// }
A service with:
import { prisma } from "../../lib/prisma"
import { Service } from "typedi"
import { IssueGroupInput } from "./inputs/create.input"
import { Resolver } from "type-graphql"
import { IssueGroup } from "./issueGroup.model"
#Service()
#Resolver(() => IssueGroup)
export class IssueGroupService {
async createIssueGroup(data: IssueGroupInput) {
return await prisma.issueGroup.create({
data,
})
}
async deleteIssueGroup(id: string) {
return await prisma.issueGroup.delete({ where: { id } })
}
async updateIssueGroup(id: string, data: IssueGroupInput) {
const issueGroup = await prisma.issueGroup.findUnique({ where: { id } })
if (!issueGroup) {
throw new Error("Issue not found")
}
return await prisma.issueGroup.update({ where: { id }, data })
}
async getAllIssueGroups() {
return (await prisma.issueGroup.findMany({orderBy: {title: 'asc'}}))
}
async getIssueGroup(id: string) {
return await prisma.issueGroup.findUnique({
where: {
id,
},
})
}
}
When I try to delete the issueGroup (which does not currently have any issues, I can see an error that points to issue.delete and says:
operation failed because it depends on one or more records that were
required but not found. Record to delete does not exist.
In my form I have:
import * as React from "react"
import { gql } from "#apollo/client"
import type { IssueGroupInput } from "lib/graphql"
import { QueryMode, Role, SortOrder, useAllIssueGroupsQuery, useDeleteIssueGroupMutation } from "lib/graphql"
const __ = gql`
query AllIssueGroups {
allIssueGroups {
id
title
description
}
}
mutation deleteIssueGroup($id: String!) {
deleteIssueGroup(id: $id) {
id
title
description
issues // I have tried both with and without issues in this list
}
}
`
export default function IssueGroups() {
const [deleteIssueGroup] = useDeleteIssueGroupMutation()
const { data, loading, refetch } = useAllIssueGroupsQuery({
fetchPolicy: "cache-and-network",
})
const allIssueGroups = data?.allIssueGroups
const onDeleteIssueGroup = (id: string) => {
return (
deleteIssueGroup({ variables: { id } }).then(() => refetch())
)
}
return (
<List>
{data?.allIssueGroups.map((issueGroup) => (
<ListItem key={issueGroup.id}>
{issueGroup.title}{issueGroup.description}
<Button onClick={() => onDeleteIssueGroup(issueGroup.id)}>Delete</Button>
</ListItem>
))}
</List>
)
}
I have seen this page of the prisma documentation and I think I have followed its advice for how to deal with an issue when the parent issueGroup is deleted.
model IssueGroup {
id String #id #default(dbgenerated("gen_random_uuid()")) #db.Uuid
title String
description String
issues Issue[]
createdAt DateTime #default(now()) #db.Timestamptz(6)
updatedAt DateTime #default(now()) #updatedAt #db.Timestamptz(6)
}
model Issue {
id String #id #default(dbgenerated("gen_random_uuid()")) #db.Uuid
title String
description String
issueGroup IssueGroup #relation(fields: [issueGroupId], references: [id], onDelete: SetNull, onUpdate: Cascade)
issueGroupId String #db.Uuid
subscribers UserIssue[]
createdAt DateTime #default(now()) #db.Timestamptz(6)
updatedAt DateTime #default(now()) #updatedAt #db.Timestamptz(6)
}
However, VS code thinks this is an error. It gives me an error message that says:
The onDelete referential action of a relation should not be set to
SetNull when a referenced field is required. We recommend either to
choose another referential action, or to make the referenced fields
optional.
My db is psql, which the prisma docs suggest, should allow SetNull
PostgreSQL PostgreSQL is the only database supported by Prisma that
allows you to define a SetNull referential action that refers to a
non-nullable field. However, this raises a foreign key constraint
error when the action is triggered at runtime.
For this reason, when you set postgres as the database provider in the
(default) foreignKeys relation mode, Prisma warns users to mark as
optional any fields that are included in a #relation attribute with a
SetNull referential action. For all other database providers, Prisma
rejects the schema with a validation error.
I can see from this page of the docs that lists cannot be optional, so I dont think I can follow the advice in the relational page of the docs and make the issueGroup issues[] as optional.
How can i delete the issue (if there were any) at the same time as I delete the issue group?
Just make issueGroup optional
model IssueGroup {
...
issues Issue[]
...
}
model Issue {
...
issueGroup IssueGroup? #relation(fields: [issueGroupId], references: [id], onDelete: SetNull, onUpdate: Cascade)
issueGroupId String? #db.Uuid
...
}
The actual message from prisma is saying that
Prisma warns users to mark as optional any fields that are included in
a #relation attribute with a SetNull referential action
Your relationship has onDelete: SetNull - so mark it as optional

How to implement transactional management in mongo with graphql?

I'm currently working on a movie database with graphql and mongodb. When a new review is added I want to push the review id immediately to the reviews array of movie entity. I understand that I have to use transactional management. I'm trying to do it like this, but I'm getting this error : throw new MongooseError('Callback must be a function, got ' + callback);
this is the mutation where I'm trying to implement it.
import Review from "../../db/models/ReviewModel.js";
import Movie from "../../db/models/MovieModel.js";
import mongoose from "mongoose";
const generateReviewModel = () => ({
queries: {
getAll: () => Review.find({}),
getReviewByID: (id) => Review.findOne({ _id: id }),
getAllHavingKey: (keys) =>
Review.find({
_id: { $in: keys.map((key) => mongoose.Types.ObjectId(key)) },
}),
},
mutations: {
addReview: (review) => {
let session = null;
Review.startSession()
.then((_session) => {
session = _session;
return session.withTransaction(() => {
return new Review(review).save(review, {
session: session,
});
});
})
.then(() => session.endSession());
},
modifyReview: (body) => Review.findByIdAndUpdate(body.id, body.query),
deleteReview: (id) => Review.findByIdAndDelete(id),
},
});
export default generateReviewModel;

Axios Vue Js: How to get the value of this object to show in api get request url

this is my vue file which accepts the id from table. this works I can get the data id from the table row
showProd (id) {
Products.showProd().then((response) => {
console.log(show1prod.product_name)
})
.catch((error) => {
alert(error)
})
this is my config file for calling the axios.get I can reach the backend but not generating the query because this url/api sends an object I believe not the id number
export default {
async showProd(id) {
return Api.get('/products/{id}',id)
},
loadProds () {
return Api.get('/products')
}
}
First make sure your API call is correct:
export default {
showProd(id) { // async not needed, axios returns promise
return axios.get('/products/' + id)
},
loadProds () {
return axios.get('/products')
}
}
You can than call these functions:
showProd (id) {
Products.showProd(id).then((response) => { // Note the id in the call
console.log(response.data.product_name) // Use the response object
})
.catch((error) => {
alert(error)
})

How to set and get values of this form in local storage

I'm setting up a local storage for settings form , and want to set and get each value of that form in local storage of my application. What i need to add to make set and get correctly for this form?
everyone can see that the get results has error and mabe the set is not done correctly.
How to make all of that work
do i need to change set and get methods? is there anythin that i am missing ? i tried all i know but i am a beginner in local storage and ionic .
my file ts :
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators, NgForm, FormControl, ValidatorFn, AbstractControl } from '#angular/forms';
import { ToastController } from 'ionic-angular';
import { EspaceAgentPage } from '../espace-agent/espace-agent';
import { EspaceCitoyenPage } from '../espace-citoyen/espace-citoyen';
import { ChangePasswordPage } from '../change-password/change-password';
import { Storage } from '#ionic/storage';
import { PasswordService } from '../services/password.service';
import { NgModule } from '#angular/core';
#Component({
selector: 'page-settings',
templateUrl: 'settings.html',
})
export class SettingsPage {
private Form : FormGroup;
public mail: any;
public tel: any;
public data: any;
constructor(public navCtrl: NavController, public navParams: NavParams, public toastCtrl: ToastController, private formBuilder: FormBuilder, public storage: Storage)
{
this.Form = formBuilder.group({
mailadress: ['', Validators.compose([Validators.pattern('^[a-zA-Z0-9_.+-]+#[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$'),Validators.email])],
telephone: ['', Validators.compose([ Validators.pattern('[0-9]*'), Validators.minLength(8), Validators.maxLength(8)])],
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad SettingsPage');
this.getValue("stoker");
}
// set a key/value
setValue(key: string, value: any)
{
this.storage.set(key, value).then((response) => {
console.log('set' + key + ' ', response);
}).catch((error) => {
console.log('set error for ' + key + ' ', error);
});
}
// get a key/value pair
getValue(key: string) {
this.storage.get(key).then((val) => {
console.log('get ' + key + ' ', val);
this.data[key] = "";
this.data[key] = val;
}).catch((error) => {
console.log('get error for ' + key + '', error);
});
}
onChangepassword()
{
this.navCtrl.push(ChangePasswordPage);
}
onSubmit(form: NgForm)
{
this.mail=this.Form.get('mailadress').value;
this.tel=this.Form.get('telephone').value;
console.log(form.value);
this.setValue("stoker",this.mail);
this.setValue("stoker",this.tel);
this.navCtrl.push(EspaceCitoyenPage);
const toast = this.toastCtrl.create({
message: 'Modifications Enregistrées !',
duration: 4000
});
toast.present();
}
}
console results capture :
capture
it seems that you get the error in this funtion
// get a key/value pair
getValue(key: string) {
this.storage.get(key).then((val) => {
console.log('get ' + key + ' ', val);
this.data[key] = "";
this.data[key] = val;
}).catch((error) => {
console.log('get error for ' + key + '', error);
});
}
when you try to get stoker key returns a null reference and then the error. Maybe there is not item stored for this key or the palform was not ready when you call the storage.
When you work arround the storage you shoud wait from the platform to be ready like this:
import { Platform } from '#ionic/angular';
import { NativeStorage } from '#ionic-native/native-storage/ngx';
-----
constructor(private storage: NativeStorage, private plt: Platform) {}
this.plt.ready().then(() => {
// call native storage
});
And think is better use Native Storage than ionic storage.
Hope this help you.
plsease refer this
import { NativeStorage } from '#ionic-native/native-storage/ngx';
constructor(private nativeStorage: NativeStorage) { }
import { NativeStorage } from '#ionic-native/native-storage/ngx';
constructor(private nativeStorage: NativeStorage) { }
this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
this.nativeStorage.getItem('myitem')
.then(
data => console.log(data),
error => console.error(error)
);
this.nativeStorage.setItem('myitem', {property: 'value', anotherProperty: 'anotherValue'})
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
this.nativeStorage.getItem('myitem')
.then(
data => console.log(data),
error => console.error(error)
);
localstorage.setitem('your key as your wish',your value),
all storage value are stored in string
ex;-
localstorage.setitem('key', value)
localstorage.getitem('key')
You can use
Windows.localstorage.setitem('key', value)

How to replace a manual id with an ObjectID _id in mongoDB?

Let's say I have a database with two collections, kids and classes. Each kid belongs to one class.
Each class has a previously created integer id.
I want to replace the kid.class_id with the (ObjectID) _id of the class, not the (integer) id of the class.
However, when I run the script below, it doesn't reset the class_id with the class._id -- it remains the old integer id.
mongoose.connect(someMongodbUri, { useMongoClient: true }, (err, db) => {
let kidsCount = 0;
db.collection('kids').find({}).each((err, kid) => {
kidsCount++;
db.collection('classes')
.findOne({ id: kid.class_id })
.then((class, err) => {
let newClassId = class._id;
db.collection('kids').updateOne(
{ _id: kid._id },
{ $set: { class_id: newClassId } }
).then(() => {
console.info('Updated', kid.class_id);
kidsCount--;
if (kidsCount === 0) { db.close(); }
});
});
});
});
Am I missing something? Thanks for any help you can offer!
We can convert integerId to Object id.
var ObjectId = require('mongodb').ObjectID;
let newClassId = ObjectId(class._id);
There may be better or elegent ways that i don't know, but this works for me.