javascriptangulardexie

How to properly use nullable/optional values in Dexie JS?


I apologize if the title is a little vague as it's hard to explain in only one short sentence, but here's what I'm trying to do:

In Angular 17 with DexieJS, I have the following object:

export interface IView {
 x?: number,
 y?: number,
 z?: number,
 id: string,
 name?: string,
}

The coordinates and the name are optional because although I will need them, they're not accessible from every part of the application.

For the database, I have the following:

export class MyDB extends Dexie {
  viewDatabase!: Table<IView, string>;
  constructor() {
      super('database');
      this.version(1).stores({
         viewDatabase: 'id',
      });
    }
}
export const db = new MyDB();

And I have the following get/set functions in another class:

async getView(id: string) {
   return db.viewDatabase
      .where('id')
      .equals(id)
      .first((data) => {
        return data;
      });
}

async addOrUpdateView(view: IView) {
    return db.viewDatabase.put(view);
}

And finally, this is what I'm trying to achieve:

Because some of the values in iView are optional, I want the database to not overwrite those values with undefined/null if a value passed in doesn't have all of them. Instead, I want it to detect if there's already values in there for the optional variables, and if so, just keep them and add the new stuff on top. I.e, if I initialize the following into the database:

{
  x: 1,
  y: 2,
  z: 3,
  id: '109210abc',
  name: 'test'
}

And then later I push the following value to the database, which has the same id (because I want to overwrite the values):

{
  x: 5,
  id: '109210abc',
  name: 'test_updated'
}

I want the database to keep the original values for y and z because they were not changed. I don't want them to automatically get set to undefined or null. I only want x and the name to change since those are the only values that changed.

I understand I could do this manually by reading the database first, grabbing what's in there, and then making a new value composed of both old and new data, but this is really tedious, especially in a large program where you may have to wait for the database to respond. Is there a way to do this automatically or at least more efficiently?

In the current program, it's not working correctly because the optional values just keep getting removed/reset if they're not defined when I save the value. I'm looking for a solution that allows me to keep the values as optional, if possible.


Solution

  • It sounds as you could use Table.update() for this.

    db.viewDatabase.update('109210abc', {
      x: 5,
      name: 'test_updated'
    });
    

    This will only update x and name and keep the rest as it was before.