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

Receiving property.type is not a function #5

Open
lp-bayramali opened this issue Dec 24, 2019 · 28 comments
Open

Receiving property.type is not a function #5

lp-bayramali opened this issue Dec 24, 2019 · 28 comments
Labels
bug Something isn't working

Comments

@lp-bayramali
Copy link

Using express server.

Received error stack:

TypeError: property.type is not a function
    at ExtendedRecord.toJSON (C:\Users\HP\Documents\demo-app-api\node_modules\admin-bro-typeorm\src\ExtendedRecord.ts:79:43)
    at C:\Users\HP\Documents\demo-app-api\node_modules\admin-bro\lib\backend\controllers\api-controller.js:120:45
    at Array.map (<anonymous>)
    at ApiController.search (C:\Users\HP\Documents\demo-app-api\node_modules\admin-bro\lib\backend\controllers\api-controller.js:120:24)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at handler (C:\Users\HP\Documents\demo-app-api\node_modules\admin-bro-expressjs\plugin.js:56:22)
@Arteha
Copy link
Owner

Arteha commented Dec 24, 2019

Hello.
Could you give information from the list below:

  1. admin-bro version
  2. admin-bro-expressjs version
  3. admin-bro-typeorm version
  4. An example when it happens (models and the options passed to admin-bro enough i think)

@lp-bayramali
Copy link
Author

Hi,

Versions and env details:

  1. admin-bro: "^1.5.2"
  2. admin-bro-expressjs: "^0.4.0"
  3. admin-bro-typeorm: "^0.1.6-alpha.2"
  4. typeorm: "^0.2.21",

Database is postgres. Database server version is Postgres 12

AdminBroOptions:

  const app = express()
   const port = 3000


   const options: AdminBroOptions = {
       // databases: [connection],
       resources: [User, ProfilePreferences]
   }

User entity

import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    Unique,
    CreateDateColumn,
    UpdateDateColumn,
    OneToMany,
    ManyToOne,
    OneToOne,
    JoinColumn,
    BaseEntity
} from "typeorm";
import { Length, IsNotEmpty } from "class-validator";
import * as bcrypt from "bcryptjs";
import {Exclude} from "class-transformer";
import { ResetPasswordToken } from "./ResetPasswordToken";
import { Role } from "./Role";
import { Post } from "./Post";
import { PostLikes } from "./PostLike";
import { PostComments } from "./PostComment";
import { PostReport } from "./PostReport";
import { ProfilePreferences } from "./ProfilePreferences";

@Entity()
@Unique(["username"])
export class User extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number;

    @Column({type: 'varchar'})
    @Length(4, 20)
    username: string;

    @Column({type: 'varchar'})
    @Length(2, 20)
    firstName: string;

    @Column({type: 'varchar'})
    @Length(2, 20)
    lastName: string;

    @Column({type: 'varchar'})
    @Length(2, 20)
    email: string;

    @Column({type: 'varchar'})
    @Length(4, 100)
    @Exclude()
    password: string;

    @OneToMany(type => ResetPasswordToken, token => token.user)
    resetPasswordTokens: ResetPasswordToken[];

    @OneToMany(type => Post, post => post.user)
    posts: Post[];

    @OneToMany(type => PostLikes, postLike => postLike.user)
    likes: PostLikes[];

    @OneToMany(type => PostComments, postComment => postComment.user)
    comments!: PostComments[];

    @OneToMany(type => PostReport, postReport => postReport.user)
    reports!: PostReport[];

    @OneToOne(type => ProfilePreferences, profilePreferences => profilePreferences.user, {cascade: true, onDelete: 'CASCADE'})
    @JoinColumn() // Adds foreign key profileSettingsId to User.
    profilePreferences!: ProfilePreferences;

    @Column()
    @CreateDateColumn()
    createdAt: Date;

    @Column()
    @UpdateDateColumn()
    updatedAt: Date;

    @ManyToOne(type => Role, role => role.users)
    role: Role;

    hashPassword() {
        this.password = bcrypt.hashSync(this.password, 8);
    }

    checkIfUnencryptedPasswordIsValid(unencryptedPassword: string) {
        return bcrypt.compareSync(unencryptedPassword, this.password);
    }
} 

ProfilePreference Entity


import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    OneToOne,
    BaseEntity
} from "typeorm";
import { Length } from "class-validator";
import { User } from "./User";
import { ProfileDisplayAs, AvailableLanguages } from "../models/profile";

@Entity()
export class ProfilePreferences extends BaseEntity {

    constructor() {
        super();
        
        this.preferedLanguage = AvailableLanguages.ENGLISH;
        this.profileDisplayAs = ProfileDisplayAs.NAME_SURNAME;
        this.profilePictureUrl = "";
        this.enabledCategoryNotifications = [];
    }

    @PrimaryGeneratedColumn()
    id: number;

    @Column({type: 'varchar'})
    @Length(4, 20)
    preferedLanguage: AvailableLanguages;

    @Column("simple-json", { nullable: true })
    enabledCategoryNotifications: { id: number, name: string }[];

    @Column({type: 'varchar'})
    @Length(2, 256)
    profilePictureUrl: string;

    @Column({type: 'varchar'})
    @Length(2, 64)
    profileDisplayAs: ProfileDisplayAs;

    @OneToOne(type => User, user => user.profilePreferences)
    user!: User;
}

Generated query and error message


Admin panel app listening on port 3000!
query: SELECT "ProfilePreferences"."id" AS "ProfilePreferences_id", "ProfilePreferences"."preferedLanguage" AS "ProfilePreferences_preferedLanguage", "ProfilePreferences"."enabledCategoryNotifications" AS "ProfilePreferences_enabledCategoryNotifications", "ProfilePreferences"."profilePictureUrl" AS "ProfilePreferences_profilePictureUrl", "ProfilePreferences"."profileDisplayAs" AS "ProfilePreferences_profileDisplayAs" FROM "profile_preferences" "ProfilePreferences" ORDER BY "ProfilePreferences"."id" ASC LIMIT 10
query: SELECT COUNT(DISTINCT("ProfilePreferences"."id")) as "cnt" FROM "profile_preferences" "ProfilePreferences"
TypeError: property.type is not a function
    at ExtendedRecord.toJSON (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro-typeorm\src\ExtendedRecord.ts:79:43)
    at C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro\lib\backend\actions\list-action.js:92:44
    at Array.map (<anonymous>)
    at Object.handler (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro\lib\backend\actions\list-action.js:92:33)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at ActionDecorator.handler (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro\lib\backend\decorators\action-decorator.js:66:15)      
    at handler (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro-expressjs\plugin.js:56:22)

Some details and comments:

Issue is happening when I'm clicking to any Entity name on AdminBro sidenav. Items are not listing. Item count is always 0.

@lp-bayramali
Copy link
Author

The same error is retrieving for any of entities


query: SELECT "User"."id" AS "User_id", "User"."username" AS "User_username", "User"."firstName" AS "User_firstName", "User"."lastName" AS "User_lastName", "User"."email" AS "User_email", "User"."password" AS "User_password", "User"."createdAt" AS "User_createdAt", "User"."updatedAt" AS "User_updatedAt", "User"."profilePreferencesId" AS "User_profilePreferencesId", "User"."roleId" AS "User_roleId" FROM "user" "User" ORDER BY "User"."email" ASC LIMIT 50
TypeError: property.type is not a function
    at ExtendedRecord.toJSON (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro-typeorm\src\ExtendedRecord.ts:79:43)
    at C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro\lib\backend\controllers\api-controller.js:120:45
    at Array.map (<anonymous>)
    at ApiController.search (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro\lib\backend\controllers\api-controller.js:120:24)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at handler (C:\Users\HP\Documents\gostivar-app-api\node_modules\admin-bro-expressjs\plugin.js:56:22)

I did run the query manually on DB IDE and query returns the data without any problem. Generated query is okay

@Arteha
Copy link
Owner

Arteha commented Dec 24, 2019

Probably you forgot to register adapter before running AdminBro route.
try this:

import { Database, Resource } from "admin-bro-typeorm";
import AdminBro from 'admin-bro'

AdminBro.registerAdapter({ Database, Resource });

@lp-bayramali
Copy link
Author

lp-bayramali commented Dec 24, 2019

Probably you forgot to register adapter before running AdminBro route.
try this:

import { Database, Resource } from "admin-bro-typeorm";
import AdminBro from 'admin-bro'

AdminBro.registerAdapter({ Database, Resource });

Nope, adapter is registered already.

Here is the starter method:

import { Database, Resource } from "admin-bro-typeorm";


createConnection().then(async connection => {
    const app = express()
    const port = 3000

    const options: AdminBroOptions = {
        // databases: [connection],
        resources: [User, ProfilePreferences, Category]
    }
    const adminBro = new AdminBro(options)
    const router = AdminBroExpress.buildRouter(adminBro)

    app.get('/', (req, res) => res.send('Hello World!'))
    app.use(adminBro.options.rootPath, router)

    app.listen(port, () => console.log(`Admin panel app listening on port ${port}!`))

}).catch(error => console.log(error));

@lp-bayramali
Copy link
Author

After some debugging, for Entity properties like relations Property.type() is throwing an error.

I added this falsy check for property && property.type and I'm able to get record without any problem.

image

@Arteha
Copy link
Owner

Arteha commented Dec 25, 2019

Your idea doesn't solve the problem. Try to console.log(property instanceof Property, property) and lets see what is it.

import { Database, Resource } from "admin-bro-typeorm";


createConnection().then(async connection => {
    const app = express()
    const port = 3000

    const options: AdminBroOptions = {
        // databases: [connection],
        resources: [User, ProfilePreferences, Category]
    }
    const adminBro = new AdminBro(options)
    const router = AdminBroExpress.buildRouter(adminBro)

    app.get('/', (req, res) => res.send('Hello World!'))
    app.use(adminBro.options.rootPath, router)

    app.listen(port, () => console.log(`Admin panel app listening on port ${port}!`))

}).catch(error => console.log(error));

Is it whole piece? You still missing line:

AdminBro.registerAdapter({ Database, Resource });

@lp-bayramali
Copy link
Author

Yes adapter is registered.
image

@lp-bayramali
Copy link
Author

This breaking issue still continues unfortunately

@Arteha
Copy link
Owner

Arteha commented Dec 26, 2019

Did you tried this?

console.log(property instanceof Property, property)

@Arteha Arteha added the bug Something isn't working label Dec 26, 2019
@lp-bayramali
Copy link
Author

Receiving undefined for Property. console.log fails

@Arteha
Copy link
Owner

Arteha commented Dec 27, 2019

import Property to this file.

const {Property} = require("./Property");

Then use.

@lp-bayramali
Copy link
Author

I'm adding full console.log here:

console.log(property instanceof Property, property)

Last column which is printed successfully is updateDate, then it returns TypeError: property.type is not a function. After updateDate the next one is profilePreferences which is a relation, not a column

@Arteha
Copy link
Owner

Arteha commented Dec 28, 2019

Invite me as collaborator to your repo

@lp-bayramali
Copy link
Author

Hi I added you as a collaborator to the project. There is needed some env configurations and will send you the details as an email

@Arteha
Copy link
Owner

Arteha commented Dec 30, 2019

So?

@Arteha
Copy link
Owner

Arteha commented Dec 30, 2019

@lp-bayramali

@bayraak
Copy link

bayraak commented Dec 30, 2019

I added you as a colloborator as you said @Arteha . You can see and reproduce the error if you want

@Arteha
Copy link
Owner

Arteha commented Dec 31, 2019

Send me a link to your repo.

@lp-bayramali
Copy link
Author

Here is it: REPO LINK

Admin bro integration is on this branch: feature/admin-bro-integration
The link directly references to that branch. Read README file to run the project

@FBI23
Copy link

FBI23 commented Jan 15, 2020

Also receiving the same error, only difference, I'm using Aurora MySQL.

@szalo13
Copy link

szalo13 commented Feb 14, 2020

I also had the same problem - adding if(property && typeof property.type === 'function') instead of if(property) in 44 line of ExtendedRecord fixed the problem ;>

@szalo13
Copy link

szalo13 commented Mar 3, 2020

I added bugfix to pull requests some time ago, any progress on it?

@Arteha
Copy link
Owner

Arteha commented Mar 3, 2020

@szalo13 Hello.
property must be an instance of Property class. So adding ... && typeof property.type === 'function' is a temp patch and doesn't fix problem. I need to find out what is it at all. I can't simulate the problem. Could you check is property instanceof Property and property .constructor.name ?

@Zhomart
Copy link

Zhomart commented Mar 22, 2020

I've checked it locally. n == "constructor" and typeof property == "object". property.type is undefined.

property.constructor.name == "Function".

for other fields, e.g. n == "lastName", typeof property == "property" and property.constructor.name == "Property"

@Catanix
Copy link

Catanix commented May 3, 2020

Got same problem, added:
if (property && typeof property != 'function')
and it started to work. Hope you will fix it soon.

@szalo13
Copy link

szalo13 commented May 4, 2020 via email

@Arteha
Copy link
Owner

Arteha commented May 5, 2020

The problem is patched in v0.1.6-alpha.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants