0

I am trying to load the json file first and later on want the rest to get executed. I have placed the code on top of the TypeScript file so that I could be able to load it first. Still I could not and I am getting the errors while process the variable in which I am storing the file data.
Here is the code:

import * as $ from "jquery";

export let train;
$.getJSON("t.json", function(json) {
    train = json;
    console.log(train[0]); // this will show the info it in firebug console
});

In another file I am trying to call it using the following statement:

import {train} from "./playground"

The error I am getting is something like this:

Uncaught TypeError: Cannot read property '0' of undefined
    at genGauss (bundle.js:12)
    at classifyTwoGaussData (bundle.js:12)
    at renderThumbnail (bundle.js:13)
    at drawDatasetThumbnails (bundle.js:13)
    at Object.7../dataset (bundle.js:13)
    at o (bundle.js:1)
    at r (bundle.js:1)
    at bundle.js:1

I know this is happening because the train variable is not getting inputs.
Hence I would like to know how I can load the json file on Top priority in my code so that everything will work without errors.
The HTML template I am using is available here: HTML Template

The package.json of my program look like this:

{
  "name": "deep-playground-prototype",
  "version": "2016.3.10",
  "description": "",
  "private": true,
  "scripts": {
    "clean": "rimraf dist",
    "start": "npm run serve-watch",
    "prep": "copyfiles analytics.js dist && concat node_modules/material-design-lite/material.min.js node_modules/seedrandom/seedrandom.min.js > dist/lib.js",
    "build-css": "concat node_modules/material-design-lite/material.min.css styles.css > dist/bundle.css",
    "watch-css": "concat node_modules/material-design-lite/material.min.css styles.css -o dist/bundle.css",
    "build-html": "copyfiles index.html dist",
    "watch-html": "concat index.html -o dist/index.html",
    "build-js": "browserify src/playground.ts -p [tsify] | uglifyjs -c > dist/bundle.js",
    "watch-js": "watchify src/playground.ts -p [tsify] -v --debug -o dist/bundle.js",
    "build": "npm run prep && npm run build-js && npm run build-css && npm run build-html",
    "watch": "npm run prep && concurrently \"npm run watch-js\" \"npm run watch-css\" \"npm run watch-html\"",
    "serve": "http-server -o -c-1 dist/",
    "serve-watch": "concurrently \"http-server -o -c-1 dist/\" \"npm run watch\""
  },
  "devDependencies": {
    "@types/d3": "^3.5.34",
    "@types/jquery": "^3.3.28",
    "concat": "^1.0.3",
    "concurrently": "3.1.0",
    "copyfiles": "1.0.0",
    "http-server": "^0.11.1",
    "rimraf": "2.5.4",
    "tsify": "^4.0.0",
    "typescript": "^2.9",
    "uglify-js": "^2.8.29",
    "watchify": "^3.11.0"
  },
  "dependencies": {
    "d3": "^3.5.16",
    "jquery": "^3.3.1",
    "material-design-lite": "^1.3.0",
    "seedrandom": "^2.4.3"
  }
}

Kindly help me in knowing what I missed here.

David Soergel
  • 1,709
  • 1
  • 11
  • 15
Jaffer Wilson
  • 7,029
  • 10
  • 62
  • 139
  • The AJAX request to retrieve the JSON is asynchronous, which means execution continues on past that statement while `train` is still `undefined` - hence the problem. To fix this use the callbacks or promises. – Rory McCrossan Dec 20 '18 at 10:54
  • And just to pre-empt, I'm sure someone will suggest using `async: false`, but never do that as it is incredibly bad practice. – Rory McCrossan Dec 20 '18 at 10:55
  • @RoryMcCrossan Thank you for your reply Sir. But I have gone through the link that you have submitted with regard to my question as duplicate. Please let me know why not a single solution did worked in my case. I have tried every query from there. – Jaffer Wilson Dec 20 '18 at 11:12
  • @RoryMcCrossan Sir can you just give it a try so I will know. Actually, I have tried all the 6 answers from the question and is not working. – Jaffer Wilson Dec 20 '18 at 11:23
  • To give you a solution you need to show us how and where you're using `train` after the AJAX request completes. However, in basic terms you need to execute all logic that depends on `train` being set after the callback completes - in other words, call it from where your `console.log()` is right now. – Rory McCrossan Dec 20 '18 at 11:24
  • @RoryMcCrossan That means I need to read the file everything I am trying to execute the function. But my requirement was that I load the file once and then use the variable else where. I want to get rid of loading every time. – Jaffer Wilson Dec 20 '18 at 11:28
  • In which case you need to set a boolean variable in the callback of `$.getJSON` to indicate that the load has finished. You will then need to check that this value is set to `true` to indicate the data has loaded when you come to require it. *However* this pattern is needlessly overcomplicated and creates more problems than it solves. Firstly, if the user tries to perform the action before data is loaded then you will need to tell them to wait then click the button again, which is annoying. Secondly, if the load action is that slow, then that's a problem in itself, and you should look to... – Rory McCrossan Dec 20 '18 at 11:40
  • ... reduce the data being transferred, either by filtering or paging. Thirdly, this way may end up putting more strain on your server as you are making another AJAX request when the page loads, even though the user may never see or need the data you're loading. TL;DR; just get the data when the user requests to see it and show a loading spinner while the request is in progress. This is why 99% of web systems use this pattern. – Rory McCrossan Dec 20 '18 at 11:41

0 Answers0