Skip to content

"this._changes is undefined" when adding records to auto-loaded db & collection #183

@cepm-nate

Description

@cepm-nate

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

This error shows up after saving 500,000 rows, then refreshing the browser and trying to save the next set of rows. Code is simple to replicate.

Error Code


Uncaught (in promise) TypeError: this._changes is undefined
    _createChange collection.ts:1148
    _createInsertChange collection.ts:1158
    _insertMetaWithChange collection.ts:1167
    insertOne collection.ts:726
    insert collection.ts:665

Expected behavior

No error, rows inserted into collection.

Minimal reproduction of the problem with instructions

https://jsbin.com/nejijiberu (Copy to local dev server if needed. it's hard to make LokiDB work on jsBin) Same code as below

		let testCollection; // we will assign it after persistence
		IndexedStorage.register();
		PartitioningAdapter.register();

		let idbAdapter = new IndexedStorage(dbName);
		let paAdapter = new PartitioningAdapter(
			idbAdapter,
		 	{
				paging: true, 
				pageSize: 5*1024*1024 
			}
		);

		wdb = new Loki(dbName);

		let persistenceOptions = {
			adapter: paAdapter,
			autosave: window.self === window.top,
			autosaveInterval: 1000,
			autoload: window.self === window.top,
			throttledSaves: true,
			persistenceMethod: 'indexed-storage',
		};

		wdb.initializePersistence(persistenceOptions)
		.then(() => {
			console.log('Loki Persistence initialized');
			// Initialize collection
			testCollection = wdb.getCollection('Test');
			if (!testCollection) testCollection = wdb.addCollection('Test');
			// Display number of rows IN collection
			const oldRecords = testCollection.find();
			console.log('Number of rows loaded from IndexedDB collection:',oldRecords.length);
			// Use verbose method to get maximum id of existing records.
			const oldIds = oldRecords.map((r) => parseInt(r.id));
			const oldIdsLength = oldIds.length;
			let maxId = oldIds[0] || 0;
			for (let i = 1; i < oldIdsLength; ++i) {
				if (oldIds[i] > maxId) {
					maxId = oldIds[i];
				}
			}
			// Fetch placeholder data
			fetch('https://jsonplaceholder.typicode.com/photos') 
				.then(response => response.json())
				.then(json => {
					console.log('Enlarging result set from jsonplaceholder...');
					let bSet = json;
					// Make set larger
					bSet = [
						...bSet,...bSet,...bSet,...bSet,...bSet,
						...bSet,...bSet,...bSet,...bSet,...bSet,
					];
					bSet = [
						...bSet,...bSet,...bSet,...bSet,...bSet,
						...bSet,...bSet,...bSet,...bSet,...bSet,
					];
					// bSet = [
					// 	...bSet,...bSet,...bSet,...bSet,...bSet,
					// 	...bSet,...bSet,...bSet,...bSet,...bSet,
					// ];
					console.log('Cloning',bSet.length,'records...');
					bSet = JSON.parse(JSON.stringify(bSet)); // clone so we can reset id field
					console.log('Resetting',bSet.length,'id fields, starting at',maxId+1);
					for (i = 0; i < bSet.length; i += 1) bSet[i].id = i+maxId+1; // reset id field
					console.log('Adding',bSet.length,'rows from jsonplaceholder into LokiDB...');
					testCollection.insert(bSet);
					console.log('Added rows from jsonplaceholder. Refresh to see if they stick around.');
				})

		})
		.catch((e) => console.error('initializePersistence error', e.message));

What is the motivation / use case for changing the behavior?

I need to save large numbers of records (about 2 mil) across 80 or so collections. The above bug was encountered while I was attempting to make an easy way to replicate a secondary bug.

The secondary bug: With 80 or so collections and ~2M records saved (and showing up in both IndexedDB and in memory), reloading the browser would cause the collections to vanish, even though I can still see the data sitting in IndexedDB. I figured it'd be best to focus on the primary bug first, then try to figure out why something between LokiDB, IndexedStorage, and PartitioningAdapter was failing to autoload the 80+ collections.

Environment


LokiDB version: 2.1.0

Exact same error in Firefox 81.0 and Chrome 85.0.4183.121.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions