0

I have a JavaScript file that is going to upload a file to Microsoft Dynamics CRM. This JavaScript file references another JavaScript file via RequireJS. The JavaScript file it references was compiled from several Typescript files. The Typescript files set up a model to store the data to upload as well as the logic to interact with the Dynamics API. I have read through the Typescript/RequireJS documentation as well as several related SO questions, but I haven't been able to figure out how to get the define statement in RequireJS to work correctly so that I can use my model & Dynamics API logic from my JavaScript file. Am I correctly exporting my classes from Typescript? Am I correctly defining my import in JavaScript?

Model.ts

export class ExpenseTransaction extends ModelBase {

    public Field1: string;
    public Field2: number;
    .
    .
    .

    constructor() {
        super();
    }

    toJSON(): any {
        let json = {
            "[email protected]": this.Connection + "(" + this.Field1 + ")",
            "ccseq_Field2": this.Field2, 
             .
             .
             .               
        };

        return json;

    }

}

WebAPI.ts

import * as Model from './Model';

export class ExpenseTransaction extends APIBase {

constructor() {
    super();
}

ConvertToEntity = (data: Array<Object>): Array<Model.ExpenseTransaction> => {
    let result: Array<Model.ExpenseTransaction> = new Array<Model.ExpenseTransaction>();
    for (let i: number = 0; i < data.length; i++) {

        let newRecord: Model.ExpenseTransaction = new Model.ExpenseTransaction();

        newRecord.Field1 = data[i]["_Field1_value"];
        newRecord.Field2 = data[i]["ccseq_Field2"];

        result[i] = newRecord;
    }
    return result;
}

Get(): Promise<{}> {
    let expenses: Array<Model.ExpenseTransaction>;
    let self = this;
    return new Promise((resolve, reject) => {
        $.ajax({
            url: this.ExpenseTransaction,
            type: "GET",
            contentType: "application/json",
            dataType: "json",
            success: (data: any): void => {resolve(self.ConvertToEntity(data.value));},
            error: (data: any) => { reject(data.status); }
        });
    });
};

Create(expense: Model.ExpenseTransaction): Promise<{}> {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: this.Connection,
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: JSON.stringify(expense.toJSON()),
            success: (data: any): void => {resolve(data.value);},
            error: (data: any) => {reject(data.status);}
        });
    });
};
}

Compiled Typescript

define("CCSEQ/Model", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });

    class ExpenseTransaction extends ModelBase {
        constructor() {
            super();
        }
        toJSON() {
            let json = {
                "[email protected]": this.Connection + "(" + this.Field1 + ")",
                "ccseq_Field2": this.Field2
            };
            return json;
        }
    }
    exports.ExpenseTransaction = ExpenseTransaction;

define("CCSEQ/WebAPI", ["require", "exports", "CCSEQ/Model"], function (require, exports, Model) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });

    class ExpenseTransaction extends APIBase {
        constructor() {
            super();
            this.ConvertToEntity = (data) => {
                let result = new Array();
                for (let i = 0; i < data.length; i++) {
                    let newRecord = new Model.ExpenseTransaction();
                    newRecord.Field1 = data[i]["_Field1_value"];
                    newRecord.Field2 = data[i]["Field2"];
                    result[i] = newRecord;
                }
                return result;
            };
        }
        Get() {
            let expenses;
            let self = this;
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: this.ExpenseTransaction,
                    type: "GET",
                    contentType: "application/json",
                    dataType: "json",
                    success: (data) => { resolve(self.ConvertToEntity(data.value)); },
                    error: (data) => { reject(data.status); }
                });
            });
        }
        ;
        Create(expense) {
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: this.Connection,
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    data: JSON.stringify(expense.toJSON()),
                    success: (data) => { resolve(data.value); },
                    error: (data) => { reject(data.status); }
                });
            });
        }
        ;
    }
    exports.ExpenseTransaction = ExpenseTransaction;

JavaScript.js

    requirejs.config({
    bundles: {
        '../CCSEQ.Library': ['CCSEQ/Model']
    }
})

define(["require", "../jquery-3.1.1", "../papaparse.min", "CCSEQ/Model"], function (require, jquery, Papa, Model) {
    "use strict"; 
    $(document).ready(() => {
        //$("#loading").hide();
        setupHandlers();
    });
    function setupHandlers() {
        "use strict";
        $("#csv-file").change((e) => {
            //$("#loading").show();
            let file = e.target.files[0];
            if (!file) {
                return;
            }
            Papa.parse(file, {
                complete: (results) => {
                    ImportExpenseTransaction(results.data);
                }
            });
        });
    }
    function ImportExpenseTransaction(data) {
        let importData = new Array();
        data.forEach((expense) => {
            let newRecord = new Library.Model.ExpenseTransaction();
            newRecord.Field1 = expense["Field1"];
            newRecord.Field2 = expense["Field1"];
            importData.push(newRecord);
        });
        let expenseTransactionAPI = new ExpenseTransaction();
        expenseTransactionAPI.Create(importData[0]).then(() => { console.log("success"); }).catch(() => { console.log("failure"); });
    }
});

1 Answer 1

1

You don't appear to have a module defined for ../CCSEQ.Library as that may be the file name that you have chosen, but the only id's in there are CCSEQ/Model and CCSEQ/WebAPI

Usually in AMD there would be a single module per file, but can be told to map multiple modules to a single file using some extra config (http://requirejs.org/docs/api.html#config-bundles)

requirejs.config({
  bundles: {
    'js/CCSEQ.Library': ['CCSEQ/Model', 'CCSEQ/WebAPI']
  }
})

where js/CCSEQ.Library is path to a js file relative to the baseUrl (i've assumed your compiled TS is at /js/CCSEQ.Library.js - substitute for your real path, minus the .js extension)

You would then require the modules themselves directly, which would use the lookup to load the correct parent file

require(["../jquery-3.1.1", "../papaparse.min", "CCSEQ/Model",  "CCSEQ/WebAPI"], (jquery, Papa, Model, WebAPI) {
  const myModel = new Model.ExpenseTransaction()
  const myAPI = new WebAPI. ExpenseTransaction()
})

Alternatively if you want to access via a single Library module, you will need to add another typescript module to export them...

Library.ts

import * as Model from './Model'
import * as WebAPI from './WebAPI'
export default { Model, WebAPI }

This should create a module CCSEQ/Library If you were to output your compiled TS to CCSEQ/Library.js relative to the RequireJS baseUrl you should simply be able to use it directly without extra config, otherwise do the mapping config like before

requirejs.config({
  bundles: {
    'js/CCSEQ.Library': ['CCSEQ/Library']
  }
})

require(["../jquery-3.1.1", "../papaparse.min", "CCSEQ/Library"], (jquery, Papa, Library) {
  const myModel = new Library.Model.ExpenseTransaction()
  const myAPI = new Library.WebAPI.ExpenseTransaction()
})
Sign up to request clarification or add additional context in comments.

2 Comments

I gave this a try, but didn't have any success. My Model is undefined.
Recreated locally, using requirejs.config({ bundles: { 'somedir/CCSEQ.Library': ['CCSEQ/Model', 'CCSEQ/WebAPI'] } }) require(['CCSEQ/Model', 'CCSEQ/WebAPI'], function (Model, WebAPI) { const myModel = new Model.ExpenseTransaction() const myAPI = new WebAPI.ExpenseTransaction() }) correctly loads your modules form the single file, but there is error within the module itself, as your typescript isn't importing ModelBase or APIBase

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.