question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't insert records when using Typescript.

See original GitHub issue

I’m struggling for more than 4 hours now in one of the most basic operations with Sequelize using the Typescript example from the doc. I’m simply trying to store a simple record in SQL Server. I came to the conclusion that it’s either a gigantic bug sitting somewhere OR the doc is omitting something crucial. Here is the code.

What are you doing?

// connection.ts
export const sequelize = new Sequelize('mssql://sa:test@test:1433/Test', {
    dialectOptions: {
        instanceName: "SQLEXPRESS",
    }
});

// model.ts
class MemberInfo extends Model {
    public memb_guid!: number;
    public memb___id!: string;
    public memb__pwd!: string;
    public memb_name!: string;
    public sno__numb!: string;
    public bloc_code!: string;
    public ctl1_code!: string;
    public post_code!: string  | null;
    public addr_info!: string  | null;
    public addr_deta!: string  | null;
    public mail_addr!: string  | null;
    public fpas_ques!: string  | null;
    public fpas_answ!: string  | null;
    public mail_chek!: boolean | null;
}

MemberInfo.init({
    memb_guid: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        allowNull: false
    },
    memb___id: {
        type: DataTypes.STRING(10),
        primaryKey: true,
        allowNull: false
    },
    memb__pwd: {
        type: DataTypes.STRING,
        allowNull: false
    },
    memb_name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    sno__numb: {
        type: DataTypes.STRING,
        allowNull: false
    },
    post_code: {
        type: DataTypes.STRING,
        allowNull: true
    },
    addr_info: {
        type: DataTypes.STRING,
        allowNull: true
    },
    addr_deta: {
        type: DataTypes.STRING,
        allowNull: true
    },
    tel__numb: {
        type: DataTypes.STRING,
        allowNull: true
    },
    phon_numb: {
        type: DataTypes.STRING,
        allowNull: true
    },
    mail_addr: {
        type: DataTypes.STRING,
        allowNull: true
    },
    fpas_ques: {
        type: DataTypes.STRING,
        allowNull: true
    },
    fpas_answ: {
        type: DataTypes.STRING,
        allowNull: true
    },
    job__code: {
        type: DataTypes.STRING,
        allowNull: true
    },
    appl_days: {
        type: 'SMALLDATETIME',
        allowNull: true
    },
    modi_days: {
        type: 'SMALLDATETIME',
        allowNull: true
    },
    out__days: {
        type: 'SMALLDATETIME',
        allowNull: true
    },
    true_days: {
        type: 'SMALLDATETIME',
        allowNull: true
    },
    mail_chek: {
        type: DataTypes.STRING,
        allowNull: true
    },
    bloc_code: {
        type: DataTypes.STRING,
        allowNull: false
    },
    ctl1_code: {
        type: DataTypes.STRING,
        allowNull: false
    }
}, {
    sequelize,
    tableName: 'MEMB_INFO',
    timestamps: false,
    freezeTableName: true,
});

export { MemberInfo };

// Using
const account = await MemberInfo.create({
            memb___id: input.username,
            memb__pwd: input.password,
            memb_name: input.username,
            mail_addr: input.email,
            fpas_ques: input.secretQuestion,
            fpas_answ: input.secretAnswer,
            bloc_code: '0',
            ctl1_code: '0',
            sno__numb: "2019-06-19",
});

The create statement throws the following error (even though the values are all passed in valid):

notNull Violation: MemberInfo.memb_name cannot be null,
notNull Violation: MemberInfo.sno__numb cannot be null,
notNull Violation: MemberInfo.bloc_code cannot be null,
notNull Violation: MemberInfo.ctl1_code cannot be null

The fun fact is that when I console.log in the beforeValidate hook you can see a very awkward behaviour of the dataValue and _previousDataValues

MemberInfo {
  dataValues:
   { memb___id: 'ddddd',
     memb__pwd: undefined,
     memb_name: undefined,
     mail_addr: undefined,
     fpas_ques: undefined,
     fpas_answ: undefined,
     bloc_code: undefined,
     ctl1_code: undefined,
     sno__numb: undefined,
     memb_guid: undefined,
     post_code: undefined,
     addr_info: undefined,
     addr_deta: undefined,
     mail_chek: undefined },
  _previousDataValues:
   { memb___id: undefined,
     memb__pwd: 'ddddd',
     memb_name: 'ddddd',
     mail_addr: 'ddd@sss.xom',
     fpas_ques: 'ssssss',
     fpas_answ: 'ssssss',
     bloc_code: '0',
     ctl1_code: '0',
     sno__numb: '2019-06-19',
     memb_guid: undefined,
     post_code: undefined,
     addr_info: undefined,
     addr_deta: undefined,
     mail_chek: undefined },
  _changed:
   { memb___id: true,
     memb__pwd: true,
     memb_name: true,
     mail_addr: true,
     fpas_ques: true,
     fpas_answ: true,
     bloc_code: true,
     ctl1_code: true,
     sno__numb: true,
     memb_guid: true,
     post_code: true,
     addr_info: true,
     addr_deta: true,
     mail_chek: true },

During those hours of debugging I found out that if i remove (any or all) properties from the class, then the value gets populated correctly in the dataValues.

If I remove them all it actually saves! But I just lost typescript type safety here.

One another thing I was also suspecting is that I’m using webpack + babel + typescript setup (for other reasons), but I couldn’t find anything which could compromise the properties of the Model class definition.

I’ll post my babelrc just in case:

{
  "presets": [
    ["@babel/env", {
      "modules": false,
      "targets": {
        "node": "current"
      }
    }], "@babel/preset-react", "@babel/typescript"
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true } ],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
    ["module-resolver", {
      "root": ["./"],
      "alias": {
        "modules": "./src/client/modules"
      }
    }],
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-transform-runtime",
    "universal-import",
    "react-hot-loader/babel"
  ]
}

If i use the define way of creating my models all works fine. It’s just wayyyy uglier 😄

What do you expect to happen?

That save just fine!

Environment

Dialect:

  • mysql
  • postgres
  • sqlite
  • mssql
  • any Dialect library version: 6.1.2 Database version: 2008r2 Sequelize version: 5.8.7 Node Version: 10 OS: MacOS If TypeScript related: TypeScript version: 3.4.1 Tested with latest release:
  • No
  • Yes, specify that version:

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
levibostiancommented, Sep 23, 2019

I encountered this issue yesterday afternoon and I did some debugging with the sequelize source code. Read below for (1) solution(s) to the problem (2) my findings from debugging on the problem (3) and my proposed long-term solution to the problem.

TL;DR - If using Babel (which probably means you’re using the @babel/plugin-proposal-class-properties plugin), create a custom constructor in your class:

import {Model as SequelizeModel} from "sequelize"

export class OAuthAppSequelizeModel extends SequelizeModel {
  public id: number
  public clientId: string
  public clientSecret: string
  public createdAt: Date
  public updatedAt: Date

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  constructor(values: any = {}, options: object = {}) {
    super(values, options)

    this.id = values.id
    this.clientId = values.clientId
    this.clientSecret = values.clientSecret
    this.createdAt = values.createdAt
    this.updatedAt = values.updatedAt
  }
}

…or…

Remove the @babel/plugin-proposal-class-properties plugin. I was originally using it for static properties of classes in 1 module and refactored my code to remove it.


If you want to figure out why I chose this solution and my findings from debugging this issue, read on.

Env

Type of application: Nodejs backend app Dialect: Postgres Dialect library version: (pg) 6.4.2 Database version: 2.6 Sequelize version: 5.19.0 Node Version: 10 OS: MacOS If TypeScript related: TypeScript version: 3.4.2

Babel versions:

    "@babel/cli": "^7.4.3",
    "@babel/core": "^7.4.3",
    "@babel/node": "^7.2.2",
    "@babel/plugin-proposal-class-properties": "^7.4.4",
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "@babel/preset-env": "^7.4.3",
    "@babel/preset-typescript": "^7.3.3",

Babel config:

{
  "presets": [["@babel/env", {
    "targets": {
      "node": "current"
    }
    }], "@babel/preset-typescript"],  
    "plugins": [
      "babel-plugin-transform-typescript-metadata",
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }],
      ["module-resolver", {
        "root": ["."],
        "alias": {
          "@app": "./app",
          "@test": "./tests"
        }
        }]
      ],
      "env": {
        "debug": {
          "sourceMaps": "inline",
          "retainLines": true
        }
      }
    }

Code

import {Model as SequelizeModel} from "sequelize"

export class OAuthAppSequelizeModel extends SequelizeModel {
  public id!: number
  public clientId!: string
  public clientSecret!: string
  public createdAt!: Date
  public updatedAt!: Date

  static initModel(sequelize: Sequelize): void {
    OAuthAppSequelizeModel.init(
      {
        clientId: { type: DataTypes.STRING, allowNull: false, unique: true },
        clientSecret: { type: DataTypes.STRING, allowNull: false, unique: true }
      },
      {
        modelName: "oauth_app",
        sequelize: sequelize
      }
    )
  }  

  static setupAssociations(): void {}

  getModel(): OAuthAppModel {
    return new OAuthAppModel(
      this.id,
      this.clientId,
      this.clientSecret,
      this.createdAt,
      this.updatedAt
    )
  }
}

export class OAuthAppModel implements Model<OAuthAppPublic> {
  constructor(
    public id: number,
    public clientId: string,
    public clientSecret: string,
    public createdAt: Date,
    public updatedAt: Date
  ) {}

  static async create(clientId: string, clientSecret: string): Promise<OAuthAppModel> {
	let res = await OAuthAppSequelizeModel.create({
		clientId: clientId
	    clientSecret: clientSecret
	})

    return res.getModel()
  }
}

let sequelizeConfig: Options = {
  database: databaseConnection.database,
  username: databaseConnection.username,
  password: databaseConnection.password,
  host: databaseConnection.host,
  dialect: databaseConnection.dialect,
  port: databaseConnection.port,
  define: {
    underscored: false, 
    freezeTableName: true, database.
    timestamps: true, 
    paranoid: false 
  },
  logging: true
}
sequelize = new Sequelize(sequelizeConfig)

OAuthAppSequelizeModel.initModel(sequelize)

Then, to use this API:

let oauthModel: OAuthAppModel = await OAuthAppModel.create("clientIdHere", "clientSecretHere")

Error

When I run my Typescript application, I am getting the same error as everyone else:

SequelizeValidationError: notNull Violation: oauth_app.clientId cannot be null,
     notNull Violation: oauth_app.clientSecret cannot be null

       at Promise.all.then (node_modules/sequelize/lib/instance-validator.js:74:15)
       at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
       at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:517:31)
       at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:574:18)
       at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:619:10)
       at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:699:18)
       at Promise._fulfill (node_modules/bluebird/js/release/promise.js:643:18)
       at PromiseArray._resolve (node_modules/bluebird/js/release/promise_array.js:126:19)
       at PromiseArray._promiseFulfilled (node_modules/bluebird/js/release/promise_array.js:144:14)
       at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:579:26)
       at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:619:10)
       at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:699:18)
       at _drainQueueStep (node_modules/bluebird/js/release/async.js:138:12)
       at _drainQueue (node_modules/bluebird/js/release/async.js:131:9)
       at Async.Object.<anonymous>.Async._drainQueues (node_modules/bluebird/js/release/async.js:147:5)
       at Immediate.Async.drainQueues [as _onImmediate] (node_modules/bluebird/js/release/async.js:17:14)

My findings

  1. When I build my app via Babel, this error occurs. When I run the application with tsc, no error.

Here is the key output differences with the babel output and the tsc output that I believe is causing the issue:

babel

class OAuthAppSequelizeModel extends _type.SequelizeModel {
  constructor(...args) {
    super(...args);
    this.id = void 0;
    this.clientId = void 0;
    this.clientSecret = void 0;
    this.createdAt = void 0;
    this.updatedAt = void 0;
  }
  ...
}

tsc

class OAuthAppSequelizeModel extends type_1.SequelizeModel {
    static initModel(sequelize) {
        OAuthAppSequelizeModel.init({
            clientId: { type: sequelize_1.DataTypes.STRING, allowNull: false, unique: true },
            clientSecret: { type: sequelize_1.DataTypes.STRING, allowNull: false, unique: true }
        }, {
            modelName: "oauth_app",
            sequelize: sequelize
        });
    }
    static setupAssociations() { }
    getModel() {
        return new OAuthAppModel(this.id, this.clientId, this.clientSecret, this.createdAt, this.updatedAt);
    }
}

Full outputs if you find it interesting…

babel produces this output for my class:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.OAuthAppModel = exports.OAuthAppSequelizeModel = void 0;

var _sequelize = require("sequelize");

var _type = require("./type");

class OAuthAppSequelizeModel extends _type.SequelizeModel {
  constructor(...args) {
    super(...args);
    this.id = void 0;
    this.clientId = void 0;
    this.clientSecret = void 0;
    this.createdAt = void 0;
    this.updatedAt = void 0;
  }

  static initModel(sequelize) {
    OAuthAppSequelizeModel.init({
      clientId: {
        type: _sequelize.DataTypes.STRING,
        allowNull: false,
        unique: true
      },
      clientSecret: {
        type: _sequelize.DataTypes.STRING,
        allowNull: false,
        unique: true
      }
    }, {
      modelName: "oauth_app",
      sequelize: sequelize
    });
  }

  static setupAssociations() {}

  getModel() {
    return new OAuthAppModel(this.id, this.clientId, this.clientSecret, this.createdAt, this.updatedAt);
  }

}

exports.OAuthAppSequelizeModel = OAuthAppSequelizeModel;

class OAuthAppModel {
  constructor(id, clientId, clientSecret, createdAt, updatedAt) {
    this.id = id;
    this.clientId = clientId;
    this.clientSecret = clientSecret;
    this.createdAt = createdAt;
    this.updatedAt = updatedAt;
  }

  static findByClientId(clientId) {
    return OAuthAppSequelizeModel.findOne({
      where: {
        clientId: clientId
      }
    }).then(res => res ? res.getModel() : null);
  }

  static async create(clientId, clientSecret) {
    let built = OAuthAppSequelizeModel.build();
    built.clientId = clientId;
    built.clientSecret = clientSecret;
    let res = await built.save();
    return res.getModel();
  }

  findOrCreateSelf() {
    return OAuthAppSequelizeModel.findCreateFind({
      where: {
        id: this.id
      },
      defaults: {
        clientId: this.clientId,
        clientSecret: this.clientSecret,
        createdAt: this.createdAt,
        updatedAt: this.updatedAt
      }
    }).then(res => res[0].getModel());
  }

  publicRepresentation() {
    return {
      id: this.id
    };
  }

  privateRepresentation() {
    return {
      id: this.id,
      clientId: this.clientId,
      clientSecret: this.clientSecret
    };
  }

}

exports.OAuthAppModel = OAuthAppModel;
tsc produces this output:
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const sequelize_1 = require("sequelize");
const type_1 = require("./type");
class OAuthAppSequelizeModel extends type_1.SequelizeModel {
    static initModel(sequelize) {
        OAuthAppSequelizeModel.init({
            clientId: { type: sequelize_1.DataTypes.STRING, allowNull: false, unique: true },
            clientSecret: { type: sequelize_1.DataTypes.STRING, allowNull: false, unique: true }
        }, {
            modelName: "oauth_app",
            sequelize: sequelize
        });
    }
    static setupAssociations() { }
    getModel() {
        return new OAuthAppModel(this.id, this.clientId, this.clientSecret, this.createdAt, this.updatedAt);
    }
}
exports.OAuthAppSequelizeModel = OAuthAppSequelizeModel;
class OAuthAppModel {
    constructor(id, clientId, clientSecret, createdAt, updatedAt) {
        this.id = id;
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }
    static findByClientId(clientId) {
        return OAuthAppSequelizeModel.findOne({
            where: {
                clientId: clientId
            }
        }).then(res => (res ? res.getModel() : null));
    }
    static create(clientId, clientSecret) {
        return __awaiter(this, void 0, void 0, function* () {
            let built = OAuthAppSequelizeModel.build();
            built.clientId = clientId;
            built.clientSecret = clientSecret;
            let res = yield built.save();
            return res.getModel();
        });
    }
    findOrCreateSelf() {
        return OAuthAppSequelizeModel.findCreateFind({
            where: {
                id: this.id
            },
            defaults: {
                clientId: this.clientId,
                clientSecret: this.clientSecret,
                createdAt: this.createdAt,
                updatedAt: this.updatedAt
            }
        }).then(res => res[0].getModel());
    }
    publicRepresentation() {
        return {
            id: this.id
        };
    }
    privateRepresentation() {
        return {
            id: this.id,
            clientId: this.clientId,
            clientSecret: this.clientSecret
        };
    }
}
exports.OAuthAppModel = OAuthAppModel;
//# sourceMappingURL=oauth_app.js.map

Through my debugging of the Sequelize source, this is the behavior that I am seeing (I understand maintainers already know all of this, but I wanted to include this here for inclusion of everyone into the conversation of how to resolve this problem).

  1. When calling SequelizeMode.init() when you first setup your code base, sequelize calls the static function: Model.refreshAttributes() which sets up property setters on all of the rawAttributes for your Model so each time that you set properties on your custom Model class instance, a sequelize function runs (refs 1, 2, 3)

Now when you call: modelInstance.propertyHere = valueHere, Sequelize code will run which in result calls Sequelize.Model.set() for that property with the value.

  1. When calling SequelizeModel.create(), sequelize internally calls SequelizeModel.build() and then calls .save() on that built instance.

The static SequelizeModel.build() function has the following behavior:

class OAuthAppSequelizeModel extends _type.SequelizeModel {
  constructor(...args) {
    super(...args); 
    this.id = void 0;
    this.clientId = void 0;
    this.clientSecret = void 0;
    this.createdAt = void 0;
    this.updatedAt = void 0;
  }
}
  • The constructor takes the object given to SequelizeModel.create() into the constructor to get the values set on the new instance (see this and this).
  • Model.set() where values parameter is an object (the same object being passed to .create()), is iterated and calling Model.set() on each of the values which is where each of the properties of the Model instance is being set. When each of the properties of the Model instance get set, the sequelize function setup in SequelizeModel.init() gets called.
  • Model.set() is important to note here because it will get called twice for each property when SequelizeModel.build() is being called. One time when super() is being called in the OAuthAppSequelizeModel constructor, another time when each of the properties is being set after super() is done: this.clientId = void 0;.

The problem

This is where I believe the problem lays. Sequelize.create() creates an instance of the Model where it sets the properties of the Model instance in the constructor and then calls save() on the newly built instance. However, it does not account for manipulion of the object’s properties in between the build() and save() steps. This is understandable as Sequelize can assume that if the properties are ever manipulated in the constructor, that’s your doing.

The solution(s)

  1. Don’t use babel. The project I am working on is pretty small and doesn’t need to be maintained in a long-term fashion, so I did try out the idea of switching to tsc over babel. I quickly realized that the babel development tooling with babel-node, nodemon and others work really nicely and the tsc alterntives are not quite up to par. So, I personally felt staying with babel would be better if I could get that to work.

  2. Create custom implementation for SequelizeModel.create() that performs the operations: (1) Model.build(), (2) set the properties for a 2nd time from values object, (3) Model.save().

  3. Stop using the @babel/plugin-proposal-class-properties plugin. It’s not required and it only added value to my code when I wanted to add static properties to my classes which I refactored to avoid using static properties.

I did do this:

import { Model as _SequelizeModel, CreateOptions, Utils as SequelizeUtils, BulkCreateOptions } from "sequelize"

export abstract class SequelizeModel extends _SequelizeModel {  

  static async create2<M extends SequelizeModel>(
    this: { new (): M } & typeof SequelizeModel,
    values?: object,
    options?: CreateOptions
  ): Promise<M> {
    options = SequelizeUtils.cloneDeep(options || {});

    let built: M = this.build(values, {
      isNewRecord: true,      
      // @ts-ignore
      attributes: options.fields,
      include: options.include,
      raw: options.raw,
      silent: options.silent
    })    

    for (let key in values) {
      // @ts-ignore
      let value = values[key]

      // @ts-ignore
      built[key] = value 
    }  

    let res = await built.save()

    return Promise.resolve(res as M)
  }

}

…but what sucks is that you also need to create alternatives for findCreateFind(), findOrCreate(), and others because they all call create() internally.

  1. Fix babel messing with the constructor. In your SequelizeModel subclass, do this:
export class OAuthAppSequelizeModel extends SequelizeModel {
  public id: number
  public clientId: string
  public clientSecret: string
  public createdAt: Date
  public updatedAt: Date

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  constructor(values: any = {}, options: object = {}) {
    super(values, options)

    this.id = values.id
    this.clientId = values.clientId
    this.clientSecret = values.clientSecret
    this.createdAt = values.createdAt
    this.updatedAt = values.updatedAt
  }
}

Now, babel will produce the following:

  constructor(values = {}, options = {}) {
    super(values, options);
    this.id = void 0;
    this.clientId = void 0;
    this.clientSecret = void 0;
    this.createdAt = void 0;
    this.updatedAt = void 0;
    this.id = values.id;
    this.clientId = values.clientId;
    this.clientSecret = values.clientSecret;
    this.createdAt = values.createdAt;
    this.updatedAt = values.updatedAt;
  }
}

This is good! Babel still gets to cause the original problem with this.clientId = void 0;, but you reverse the action again with this.clientId = values.clientId;.

You lose a small bit of typescript safety with the any type, but because this is just the constructor for 1 simple class, I find this the easiest, most future-proof method to solving this problem.

Conclusion

I believe I have shown that a babel plugin is the culprit of this issue. The dialect does not have to do with this issue. I do not believe this is anything that sequelize needs to handle.

However, I do believe that sequelize needs to include a note in the documentation about this. From reading some other github issues after searching “babel”, it seems that babel and sequelize doesn’t get along sometimes. Luckily, I have only had this issue thus far. A lot of typescript users could be using babel, I propose we create a babel section in the typescript documentation explaining some of the pitfalls of using babel and how to avoid them.

1reaction
papbcommented, Oct 1, 2019

Hi @levibostian thank you very much for the detailed analysis! I agree with your suggestion and I have just created an issue about it: #11494 - Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add element to typescript Record<>
First you want to use the lowercase string . There is a difference ( String is the new-able constructor), but just know that...
Read more >
TypeScript and Google Maps | Maps JavaScript API
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. The snippet below demonstrates simple usage of Google Maps using TypeScript....
Read more >
How to use Vue 3 with TypeScript
How to add TypeScript to a Vue project. First, we'll set up a new Vue project with TypeScript using the code below: npx...
Read more >
Node.js MongoDB Insert
To insert a record, or document as it is called in MongoDB, into a collection, we use the insertOne() method. A document in...
Read more >
Using TypeScript or ES6
Actual geographical data for the maps is contained in a separate package @amcharts/amcharts4-geodata . So, if you're building maps, you will need to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found