1 Reply Latest reply on Mar 2, 2020 12:39 AM by oladayo.s

    OJET CRUD with Typescripts


      Hello experts/know hows

      cc John 'JB' Brock-Oracle, Andrew Bennett, Geertjan-Oracle


      I'm just getting into active jet development and I've chosen typescript as my preferred way forward. Whilst I am very new to typescript too, i find it more comprehend-able than pure javascript hence ts.


      My background is java and i've been doing ADF development commercially for years, so i'm looking to develop complex features/applications with jet.


      There's very little examples or tutorials on OJET typescripts and there's none for CRUD operations using oj.model and collection; this is a shame really!.


      Having created a few rest endpoints, my first ojet task is to consume and perform crud operations on these, so I'll appreciate anyone who can provide me with working typescript snippets of application workspaces that i can learn from and get the hang of this.


      Code for the typescript files I've created and tried to get to render data are below. for the life of me, i couldn't get to render any data in the UI. kindly assist.


      1. My rest endpoint has the data below



                  "addressLine1":"Stroman Knolls",
                  "addressLine2":"Suite 250",












      1. file two : MetroBusinessServices.ts


      import * as ko from "knockout";

      import { Model } from "ojs/ojmodel";

      import { Collection } from "ojs/ojmodel";

      import * as metroTypes from "./metroBusinessServiceDataTypes";

      import { ojModuleSettableProperties } from "@oracle/oraclejet/dist/types/ojmodule-element";

      //import 'ojs/ojcore';

      //declare var require: any;

      import {



      } from "./metroBusinessServiceDataTypes";



      export class MetroBusinessServices {

        accountLocationURL: string;



        constructor() {

          var self = this;

          self.accountLocationURL =





        createAccountLocationMap = function (response) {

          if (response) {

            if (response['accountLocationList']) {

              console.log("...createAccountLocationMap " + response['locationId']);


              var data = response['accountLocationList'][0];

              return {

                locationId: data['locationId'],

                locationCode: data['locationCode'],

                locationName: data['locationName'],

                addressUUID: data['addressUUID']



            return {

              locationId: response['locationId'],

              locationCode: response['locationCode'],

              locationName: response['locationName'],

              addressUUID: response['addressUUID']




        createMetroAccountLocationModel = function () {

          console.log('entering createMetroAccountLocationModel');

          var LocationModel = Model.extend({

            urlRoot: this.accountLocationURL, //urlRoot: JSON.parse(this.accountLocationURL).accountLocationList,

            parse: this.createAccountLocationMap(),

            idAttribute: 'locationId'


          //console.log('exiting createMetroAccountLocationModel');

          return new LocationModel();


        createMetroAccountLocationCollection = function () {

          //console.log('entering createMetroAccountLocationCollection');

          var AccountLocationCollection = Collection.extend({

            url: this.accountLocationURL,

            //fetchSize: 10,

            //parse: this.createAccountLocationMap,

            model: this.createMetroAccountLocationModel


          //console.log('exiting createMetroAccountLocationCollection');

          return new AccountLocationCollection();




      1. file three (main page) : CustomersViewModel.ts


      * Your about ViewModel code goes here


      import * as ko from 'knockout';

      import rootViewModel from '../appController';

      import * as ModuleElementUtils from 'ojs/ojmodule-element-utils';

      import * as AccUtils from '../accUtils';

      import { ojModule } from 'ojs/ojmodule-element';

      import axios from 'axios';

      import { Collection, Model } from 'ojs/ojmodel';

      import { MetroBusinessServices } from '../viewModels/bc/metroBusinessServices';

      import {




      } from '../viewModels/bc/metroBusinessServiceDataTypes';

      import CollectionDataProvider = require('ojs/ojcollectiondataprovider');

      import { DataProvider } from "ojs/ojdataprovider";



      import ArrayDataProvider = require('ojs/ojarraydataprovider');

      import { ojListView } from 'ojs/ojlistview';

      import 'ojs/ojlistview';

      import { ojTable } from "ojs/ojtable";

      import "ojs/ojtable";



      class CustomersViewModel {

        headerConfig: ko.Observable<ojModule['config']>;

        locationmodel: ko.Observable<string>;

        metroBusinessService: MetroBusinessServices;

        accountLocationModel: ko.Observable;


        accountLocations: ko.ObservableArray;

        locationArrayDataProvider: ArrayDataProvider<any, Object>;

        accountLocationURL: string;

        locationDataSource: ko.Observable;


        locsColl: ko.Observable;

        locations: ko.ObservableArray;


        constructor() {

          // header Config

          let self = this;

          self.locations = ko.observableArray([]);

          self.locsColl = ko.observable();

          self.locationDataSource = ko.observable();

          self.accountLocationURL =


          this.headerConfig = ko.observable({ view: [], viewModel: null });

          ModuleElementUtils.createView({ viewPath: 'views/header.html' }).then(

            view => {


                view: view,

                viewModel: rootViewModel.getHeaderModel()







        // below are a set of the ViewModel methods invoked by the oj-module component.

        // please reference the oj-module jsDoc for additional information.




         * Optional ViewModel method invoked after the View is inserted into the

         * document DOM.  The application can put logic that requires the DOM being

         * attached here.

         * This method might be called multiple times - after the View is created

         * and inserted into the DOM and after the View is reconnected

         * after being disconnected.


        connected(): void {

          AccUtils.announce('Customers page loaded.');

          document.title = 'Account Locations';

          this.metroBusinessService = new MetroBusinessServices();

          this.fetch = function (successCallBack) {


              success: successCallBack,

              error: function (jqXHR, textStatus, errorThrown) {

                console.log('Error in fetch: ' + textStatus);




          //self.accountLocationModel = ko.observable(this.metroBusinessService.createMetroAccountLocationModel());

          this.locsModel = this.metroBusinessService.createMetroAccountLocationModel();

          var xyz = Collection.extend({

            url: this.accountLocationURL,

            model: this.locsModel


          this.locations = ko.observableArray(new xyz());

          console.log('locations size = ' + this.locations.length);

          this.locationArrayDataProvider = new ArrayDataProvider(this.locations, { keyAttributes: 'locationId' });

          //this.accountLocations = ko.observable(new CollectionDataProvider.);





         * Optional ViewModel method invoked after the View is disconnected from the DOM.


        disconnected(): void {

          // implement if needed





         * Optional ViewModel method invoked after transition to the new View is complete.

         * That includes any possible animation between the old and the new View.


        transitionCompleted(): void {

          // implement if needed





      export default CustomersViewModel;