previousCommitedItems.concat is not a function.
0mars opened this issue · comments
Trying to save a document and it ends up like this
Unhandled promise rejection, [TypeError: previousCommitedItems.concat is not a function. (In 'previousCommitedItems.concat(_this8._commitedItems[key])', 'previousCommitedItems.concat' is undefined)]
Here is the code
export class UserProvider {
private model: Document;
public constructor() {
this.model = db.get('User');
this.model.load();
}
public async authorize(user: User): Promise<false | NewObject[]> {
this.removeAll();
return this.model.insert(user, true); // <<<<<<<<<<<<<<<< here
}
public get(): User {
if (this.model.count() < 1) {
throw new UserNotFoundError('User not found!');
}
return <User>this.model.data().find(e => true);
}
private removeAll() {
this.model.data().forEach(function (item) {
db.remove(item, true);
});
}
Hi @0mars, turn out recent changes of React Native version 0.60 requires some updates in order to use the library. I'll make an update soon!
@hieunc229 thanks for your response, keep me posted!
@0mars, I have pushed an update. Please update vasern
to the latest version, then follow the installation instruction
I have tested on both iOS and Android, please let me know if the issue persists
@hieunc229 wuhoo!! sure will test and get back to you
Thank you @0mars :)
@hieunc229 I'm getting
Console output:
Running application on XXXXX
undefined
undefined
undefined
undefined
I'm using expo, I guess 4 is the number of fields I'm trying to save, the unhandled promise rejection exception doesn't show anything or say anything, any ideas ?
it says the same error again
sorry, now it shows the exception
Unhandled promise rejection, [TypeError: previousCommitedItems.concat is not a function. (In 'previousCommitedItems.concat(_this8._commitedItems[key])', 'previousCommitedItems.concat' is undefined)]
- node_modules/expo/build/environment/muteWarnings.fx.js:27:24 in error
- ... 11 more stack frames from framework internals
and FYI, I tried to use AsyncStorage directly, and got the same undefined, but it was more like a loop, it kept printing undefined forever
Oh, I didn't know you were using Expo. Last time I remember, Expo doesn't directly support native modules, which vasern
is a native module. If you are just testing, you can try to eject Expo, then reinstall vasern
Secondly, if the error previousCommitedItems.concat is not a function
still show up, I guess the library hasn't been updated yet. Sometimes you will need to clear the cache.
To clear cache, run the below command:
- With Expo
exp r -c
- Without Expo
npm start -- --reset-cache
I have tried to use the latest Expo and confirm that native modules are still not supported by Expo. On their documentation, there are 2 options available which are AsyncStorage
and SQLite
@hieunc229 thanks, I have a chance to test now, and I am having problems deleting documents, but saving is apparently working properly now
Unhandled promise rejection TypeError: VasernManager.ClearDocument is not a function
private removeAll(): Promise<void> {
return this.model.removeAllRecords()
}
Hey @0mars, looks like you are using typescript. The removeAllRecords
should work but it's not an "official" feature and does not exist in the type definitions yet.
You might want to ignore the this type error (using // @ts-ignore
)
so how to remove all docs from a collection? so // @ts-ignore for remove all records shall solve it ?
Sorry for the confusion, this should ignore the type error.
// @ts-ignore
this.model.removeAllRecords()
P/s: Yes, removeAllRecords
should remove all records (or docs) from a collection
thanks, this still didn't work but the following did:
export class UserProvider {
private model: Document;
public constructor() {
this.model = db.get('User');
this.model.load();
}
public async authorize(user: User): Promise<false | NewObject[] | void> {
this.removeAll();
return this.model.insert(user, true);
}
public get(): User {
if (this.model.count() < 1) {
throw new UserNotFoundError('User not found!');
}
console.log(this.model.data()); // remark on here
return <User>this.model.data()[1];
}
private removeAll() {
this.model.data().forEach(function (item) {
db.remove(item, true);
});
}
}
client:
const userData: User = {
username: "myuser",
token: "token",
uuid: "uuid",
id: "id",
};
// console.log(userProvider.get());
userProvider.authorize(userData).then((data) => {
console.log(data);
console.log('authorized');
setTimeout(() => console.log(userProvider.get()), 1000); // wuthout this, the .get returns empty
});
// model.data() returns an array first element is an internal object I guess {id: n}
[
{
"id": "n"
},
{
"id": "id",
"username": "myuser",
"token": "token",
"uuid": "uuid"
}
]
Is there a better way of reliably getting the only real record, or maybe by using filters ? the first element is less than ideal to have, having a datastore with just metadata would be more favourable I guess
Hey @0mars, there are 2 things about the insert
function
- It will return an array of new objects (not promise)
id
field will be ignored. If you really need theid
field, you might need to use a different name. Otherwise, it will cause unexpected behavior (like creating an extra record in your example)
I made little changes and tested your example.
// UserProvider
export class UserProvider {
private model: Document;
public constructor() {
this.model = db.get('User');
// 1st updates: remove this.modal.load()
}
// 2st updates: remove `async`, return `NewObject`
public authorize(user: User): false | NewObject[] {
this.removeAll();
// 3rd updates: remove `true` since it's true by default
return this.model.insert(user);
}
public get(): User {
// 4th updates: use `length` instead of `count`
if (this.model.length() < 1) {
throw new UserNotFoundError('User not found!');
}
console.log(this.model.data()); // remark on here
// 5th updates: I guess you want to use the first record
return <User>this.model.data()[0];
}
private removeAll() {
// 6th updates: use shortcut, if it shows `TypeError`, ignore it
this.model.removeAllRecords()
}
}
const userData: User = {
username: "myuser",
token: "token",
uuid: "uuid",
// 7th updates: remove id
// id: "id",
};
// 8th updates: use returned data as an object instead of promise
const data = userProvider.authorize(userData);
console.log(data);
console.log('authorized');
Let me know how it goes!
Also, when the app started, it will need a little time to load the data. It's a good practice to get/insert/update after the data is ready.
For example, I added a ready
function within UserProvider
class
public ready(fn: Function) {
this.model.onLoaded(fn)
}
Then I can use
userProvider.ready(() => {
let user = userProvider.get()
})
const userData: User = {
username: "myuser",
token: "token",
uuid: "uuid",
};
const data = userProvider.authorize(userData);
console.log('authorized');
console.log(data);
userProvider.whenReady(() => console.log(userProvider.get())); // never gets executed
public get(): User {
if (this.model.length() < 1) {
throw new UserNotFoundError('User not found!');
}
console.log(this.model.data()); // 13 rows found
return <User>this.model.data()[0]; {'id': 'n'}
}
I removed the ID from my data definition, but I guess I have to delete all
this.model.removeAllRecords(); // creashes the app and does nothing
Unhandled promise rejection TypeError: VasernManager.ClearDocument is not a function
and does nothing, still 13 records
nothing deletes the records now :(
Alright, I remember the removeAllRecords
isn't an official feature since it was only supported on iOS
.
I have just pushed a new update to support the feature on Android
as well. Please upgrade to the latest version 0.3.61
, reset cache and try again. Let me know if any issue still exists