Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Records not saved properly #104

Closed
alex-min opened this issue Oct 21, 2018 · 8 comments
Closed

Records not saved properly #104

alex-min opened this issue Oct 21, 2018 · 8 comments
Assignees

Comments

@alex-min
Copy link

alex-min commented Oct 21, 2018

Hello,

Thanks for all the work on the library, it's exactly what we need on react-native, the api & the code is slick :).

I have a very strange issue which is hard to debug, I spent about two days of debugging but I can't find the root cause of it. I used the examples/native as a base start of my project so everything is setup mostly the same way.

When I save a record, it works temporally (the observable query part works well) but it's not saved properly in the database, it just does not save data. So when I reload the app it does not work.

I've tried to debug watermelondb to find the root cause of it but I can't find why, what I know is that for some reason, the _raw object does not get set.

the model:

import { Model, Q } from '@nozbe/watermelondb'
import { field, children, lazy } from '@nozbe/watermelondb/decorators'


export default class Account extends Model {
  static table = 'accounts'

  @field('name')
  name

  @field('initial_balance')
  initialBalance

  @field('computed_balance')
  computedBalance

  @field('currency')
  currency
}

the schema file

import { appSchema, tableSchema } from '@nozbe/watermelondb'

export const mySchema = appSchema({
  version: 4,
  tables: [
    tableSchema({
      name: 'accounts',
      columns: [
        {name: 'name', type: 'string'},
        {name: 'initial_balance', type: 'number'},
        {name: 'computed_balance', type: 'number'},
        {name: 'currency', type: 'string'}
      ]
    }),
    tableSchema({
      name: 'transactions',
      columns: [
        {name: 'account_id', type: 'string', isIndexed: true},
        {name: 'amount', type: 'number'},
        {name: 'description', type: 'string'},
        {name: 'payed_at', type: 'number'}
      ]
    }),
    tableSchema({
      name: 'blogs',
      columns: [{ name: 'name', type: 'string' }],
    }),
    tableSchema({
      name: 'posts',
      columns: [
        { name: 'title', type: 'string' },
        { name: 'subtitle', type: 'string' },
        { name: 'body', type: 'string' },
        { name: 'blog_id', type: 'string', isIndexed: true },
      ],
    }),
    tableSchema({
      name: 'comments',
      columns: [
        { name: 'body', type: 'string' },
        { name: 'post_id', type: 'string', isIndexed: true },
        { name: 'is_nasty', type: 'bool' },
      ],
    }),
  ],
})

the boot.js file

import { AppRegistry } from 'react-native'

import { Database } from '@nozbe/watermelondb'
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'

import { mySchema } from './src/models/schema'
import Blog from './src/models/Blog'
import Post from './src/models/Post'
import Comment from './src/models/Comment'
import Account from './src/models/Account'

import { createNavigation } from './src/components/helpers/Navigation'

const adapter = new SQLiteAdapter({
  dbName: 'testdb',
  schema: mySchema,
})

const database = new Database({
  adapter,
  modelClasses: [Account, Blog, Post, Comment],
})

const Navigation = createNavigation({ database })

AppRegistry.registerComponent('App', () => Navigation)

as you can see, everything is the same as the example project. I could also dump a copy of the whole repo if needed, there's nothing confidential in it, it's just a test.

to create the account I just do a

 await this.props.database.collections.get('accounts').create(account => {
   account.name = this.state.name;
   account.initialBalance = 0.0;
   account.currency = this.state.currency;
})

(the values are obviously normal, I've checked). And I do have this:

10-21 17:15:26.353 18537 22922 I ReactNativeJS: [DB] Executed batch of 1 operations (first: create on accounts) in 11.935499966144562ms

in the logs

it does work initially, you can see the new account in the view but when I reload the app, I just have an empty record from the database. I've also dumped the database and the records are indeed empty.

For the watermelondb version I've tried everything and it's still the same issue.

Does that sound like anything you have heard before?

@radex
Copy link
Collaborator

radex commented Oct 22, 2018

when you do:

const acc = await this.props.database.collections.get('accounts').create(account => {
   account.name = this.state.name;
   account.initialBalance = 0.0;
   account.currency = this.state.currency;
})

try console.log(acc._raw). Does it say what you'd expect?

@alex-min
Copy link
Author

alex-min commented Oct 22, 2018

that's a good idea, I have not thought about that. No it's full of empty values.
I've even tried to give static values to it to test but it did not work.

this code:

    let acc = await this.props.database.collections.get('accounts').create(account => {
      account.name = 'test';
      account.initialBalance = 0.1;
      account.currency = 'currency';
    });
    console.log(acc._raw);

is producing this log:

10-22 22:21:00.711 16572 18068 I ReactNativeJS: { id: '4zup0vsrn0lxklue',
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   _status: 'created',
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   _changed: '',
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   last_modified: null,
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   name: '',
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   initial_balance: 0,
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   computed_balance: 0,
10-22 22:21:00.711 16572 18068 I ReactNativeJS:   currency: '' }

That's what I don't get, the values are obviously recorded since on the view with the observable it works but because it's not saved properly, as soon as I reload the app I just get blank records.

@radex
Copy link
Collaborator

radex commented Oct 23, 2018

OK, I think I know what this is. I think you have misconfigured decorators support in your Babel config file. When you set account.name = 'x', you literally set account.name instead of calling the utter that will update account._raw.name

Have you gone through Installation guide step by step? Do you have the "legacy" option for decorators set to true?

@alex-min
Copy link
Author

Yes indeed you were right, I have something wrong setup in the babelrc, I close the issue :)

Thanks a lot! :)

@rasanu
Copy link

rasanu commented May 17, 2019

@alex-min facing same issue can you show me your codes

@alex-min
Copy link
Author

alex-min commented May 17, 2019

Please see #207 (comment)

I had

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    ["@babel/plugin-transform-flow-strip-types"],
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ]
}

instead of

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-transform-runtime", {
      "helpers": true,
      "regenerator": false
    }]
  ]
}

in my babelrc.

@kesha-antonov
Copy link

I had this issue too.

Need to move export default to bottom of file:

import { Model } from '@nozbe/watermelondb'
import { field } from '@nozbe/watermelondb/decorators'

export default class User extends Model {
  static table = 'users'

  @field('email') email
  @field('phone') phone
  @field('last_name') lastName
  @field('first_name') firstName
  @field('middle_name') middleName
}

==>

import { Model } from '@nozbe/watermelondb'
import { field } from '@nozbe/watermelondb/decorators'

class User extends Model {
  static table = 'users'

  @field('email') email
  @field('phone') phone
  @field('last_name') lastName
  @field('first_name') firstName
  @field('middle_name') middleName
}

export default User

@amhed
Copy link

amhed commented Mar 13, 2022

I'm also running into this.

schema

import { appSchema, tableSchema } from '@nozbe/watermelondb';

export const schema = appSchema({
  version: 5,
  tables: [
    tableSchema({
      name: 'wallet',
      columns: [
        { name: 'walletId', type: 'string', isIndexed: true },
        { name: 'currencyCodeStr', type: 'string', isIndexed: true },
      ],
    }),
  ],
});

Model

import { Model } from '@nozbe/watermelondb';
import { field } from '@nozbe/watermelondb/decorators';

export class WalletWMO extends Model {
  static table = 'wallet';

  @field('walletId')
  walletId!: string;

  @field('currencyCodeStr')
  currencyCodeStr!: string;
}

Code to insert

database.write(async () => {
  const table = database.get<WalletWMO>('wallet');
  const result = await table.create((record: WalletWMO) => {
    record.walletId = this.id;
    record.currencyCodeStr = this.currencyCode.rawValue;
  };);
});

And yet, the underlying `_raw values are empty/default

image

Tsconfig has

"experimentalDecorators": true,
"emitDecoratorMetadata": true,

BabelConfig has

const plugins = [
    'react-hot-loader/babel',
    ['@babel/plugin-proposal-private-methods', { loose: true }],
    ['@babel/plugin-proposal-private-property-in-object', { loose: true }],
    ['@babel/plugin-proposal-class-properties', { loose: true }],
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    [
      '@babel/plugin-transform-runtime',
      {
        helpers: true,
        regenerator: true,
      },
    ],
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants