redux-orm: Uncaught TypeError: model.invalidateClassCache is not a function

When following the examples in the documentation, I constantly get this error. It happens in the Schema, in the register method. When looping through the models being registered, the model’s class doesn’t have a invalidateClassCache method.

It’s not impossible the problem is on my side, but there’s one detail that is currently making me believe there is something more at play here: I have access to most, if not all, of the properties an object extending Model should have. I’m talking about things like querySetClass and virtualFields. I also seem to have a valid object when I use Chrome’s console and break right before the error and instantiate the current model in the loop.

I should also mention I’m using TypeScript, but this should not affect anything in the use of this library. Especially since you’re using ES6. Note that even though my code right now is not following exactly the syntax of your example, it does compile to the equivalent and I did try following your exact syntax since TypeScript really doesn’t mind if I use pure JS.

That being said, here’s the code that’s causing this error:

// Book.ts
import { fk, Model } from 'redux-orm';

export default class Book extends Model {
    public static modelName: string = 'Book';
    public static fields: any = {
        author: fk('Author'),
    };
}

// public static properties compile to Book.modelName and such
// Schema.ts
import { Schema } from 'redux-orm';
import Book from 'models/Book';

const schema = new Schema();
schema.register(Book);

export default schema;
// RootReducer.ts
import { combineReducers } from 'redux';
import Schema from 'models/Schema';

export default combineReducers({
    orm: Schema.reducer(),
});

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 22

Commits related to this issue

Most upvoted comments

@edaloicaro18 I have the same problem and I found that I missed export default <model name> while importing things. Can you check if this is your case?

Hi all, I’ve made some progress on this. This has to do with the way the library is compiled and how typescript is interpreting that compilation.

Essentially:

const Model = class Model {
  static foo() {
    return "car";
  }  
}
Model.bar = function() {
  return "far"
}

// In your TS code:
class User extends Model {
}
console.log(Model.foo()) // => "car"
console.log(User.foo()) // => ERROR!
console.log(Model.bar()) // => "far"
console.log(User.bar()) // => "far"

So, there are two solutions:

  1. Either rewrite all the static methods in this format:
Model.staticMethod = function() {
  return "Yay, I work!";
}

or

  1. Find out why the transpiling of the program (or typescript) is not playing nice.

Some Notes: When TS translates a normal class extension, it will look something like this:


const A = class A {
  static foo() {
    return "d";
  }
}
class B extends A {
}

// becomes....

	var A = (function () {
	    function A() {
	    }
	    A.foo = function () {
	        return "d";
	    };
	    return A;
	}());
	var B = (function (_super) {
	    __extends(B, _super);
	    function B() {
	        return _super.apply(this, arguments) || this;
	    }
	    return B;
	}(A));
	console.log(B.foo());

However, when it extends from Redux-ORM, it does not redefine the methods because when typescript enumerates on the object’s properties, it cannot find it because the static methods are not enumerable:

https://github.com/Microsoft/TypeScript/issues/12059

Anyone have any suggestions on how we can move forward? Would be curious to find other libraries that define static methods that work with Typescript and how they get it to work.

Has anyone with Typescript managed to get this to work? If so, how?