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

question: how to load a json file in preload only if it exists #3416

Closed
dhowe opened this issue Dec 20, 2018 · 10 comments
Closed

question: how to load a json file in preload only if it exists #3416

dhowe opened this issue Dec 20, 2018 · 10 comments

Comments

@dhowe
Copy link
Contributor

dhowe commented Dec 20, 2018

Tried this with with a try/catch in preload and got the error below, after which the sketch hangs on 'Loading'. Might be nice if there was a way to load, for example, a .json config file in preload (without being forced to use the callback version of loadJSON) and have the sketch continue if its not there...

> p5.js says: It looks like there was a problem loading your json. Try checking if the file path [config.json] is correct, or running a local server.[https://github.com/processing/p5.js/wiki/Local-server]
p5.js:62653 Uncaught (in promise) Error: [object Object]
    at p5.js:62653
@dhowe dhowe added the question label Dec 20, 2018
@limzykenneth
Copy link
Member

Does it block execution? Does it show with p5.min.js? Is the error callback called when file is not present?

The first message looks like something FES throws. The second message is it coming from this line?

@dhowe dhowe changed the title question: how to load a json file _if_ it is there, otherwise do nothing question: how to load a json file only if it is there, otherwise do nothing Jan 8, 2019
@dhowe
Copy link
Contributor Author

dhowe commented Jan 8, 2019

With both minified and non-minified v0.7.2 the sketch will hang in preload if the json file is not found, even if surrounded by a try/catch (as you suggest, the error above only shows with FES enabled). When a callback function is provided, things do work correctly. So not a big problem, as there is a workaround, but perhaps should be documented at least.

@dhowe dhowe changed the title question: how to load a json file only if it is there, otherwise do nothing question: how to load a json file in preload only if it is there, otherwise do nothing Jan 8, 2019
@dhowe dhowe changed the title question: how to load a json file in preload only if it is there, otherwise do nothing question: how to load a json file in preload only if it is there Jan 8, 2019
@Spongman
Copy link
Contributor

Spongman commented Jan 9, 2019

i'm not sure if this is intentional or not, but i think it's because the _decrementPreload() function is only called in the 'success' callback that's passed to httpDo by loadJSON.

p5.js/src/io/files.js

Lines 155 to 164 in 1f14632

function(resp) {
for (var k in resp) {
ret[k] = resp[k];
}
if (typeof callback !== 'undefined') {
callback(resp);
}
self._decrementPreload();
},

if we want failure to also progress to setup(), then i think the 'error' callback also needs to call _decrementPreload.


on a completely separate note. i noticed that the error behavior is different for these functions calling httpDo. some of them just call console.error(err):

console.error(err);

... and others throw err:

throw err;

@limzykenneth
Copy link
Member

I think this is intentional behaviour because when you are loading a file in preload without error callbacks the rest of the sketch code may be expecting sucessful load of the file if they are executed. If the sketch proceeds from preload even if it is a 404 the rest of the sketch may just error out itself expecting a file to have already been loaded.

@Spongman The inconsistency probably is due to some legacy code mixed with new code. It probably should be thrown to halt execution.

@dhowe
Copy link
Contributor Author

dhowe commented Jan 10, 2019

Is there a reason not to throw an error for the preload case, which the user could catch in the admittedly rare case where this was useful? Sketch would still terminate normally if not caught..

@Spongman
Copy link
Contributor

the problem is that the throw doesn't occur until after the loadXXX call returns (it happens during the callback). so there's no opportunity to catch. in addition, for this reason, i don't think it makes sense to throw in the httpDo callbacks. there's no user code that can catch that exception, and setup won't get called anyway, since _decrementPreload() won't have been called in that if-branch.

@meiamsome
Copy link
Member

I don't think we can reasonably achieve this in the current setup.
You can do this:

let a;
function preload() {
  a = loadJSON(url, () => {}, () => this._decrementPreload());
}

But obviously _decrementPreload is internal and should not really be used in this manner.

@Spongman you are right that throwing in those callbacks is a bit strange - mostly they just cause an uncaught promise rejection, which in most browsers is just ignored. I converted some of these to console.error already when I noticed there were some throwing and some using console.error.

This issue has implications for the promised-based revamp of this loading system (#2698) and so I'm interested in how we would want this to work going forward. In particular, we've yet to find a suitably beginner-friendly way to support preloading blocking execution that isn't confusing. Alternatively, if we had support for async setup (#3000) then you could just do preload in there and control when you resolve:

let a;
async function setup() {
  try {
    a = await loadJSONAsync(url); // This is not implemented yet
  } catch (e) {}
}

Or with current fns:

let a;
async function setup() {
  try {
    a = await new Promise((resolve, reject) => loadJSON(url, resolve, reject));
  } catch (e) {}
}

@Spongman
Copy link
Contributor

i'm strongly in favor of the await loadXXXAsync in an async setup.

let loadJSONAsync = (url) => new Promise((resolve, reject) => loadJSON(url, resolve, reject));

@limzykenneth
Copy link
Member

I think eventually we will want to move to better support promise based loadXXX functions, to be able to use it with async/await is great in terms of beginner friendlyness but from what I see this is still pretty low priority even for the library code base update to ES6.

@dhowe dhowe changed the title question: how to load a json file in preload only if it is there question: how to load a json file in preload only if it exists Jan 10, 2019
@lmccart
Copy link
Member

lmccart commented Dec 15, 2019

closing this because it is as @limzykenneth points out intended behavior and I believe difficult to implement with the current system.

@lmccart lmccart closed this as completed Dec 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants