# Loading objs with callbacks

**URL:** https://discourse.processing.org/t/loading-objs-with-callbacks/36066
**Category:** Coding Questions
**Created:** [April 1, 2022, 12:05pm UTC](https://discourse.processing.org/t/loading-objs-with-callbacks/36066 "2022-04-01T12:05:09Z")
**Posts on this page:** 1
**Showing post:** 2

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [April 1, 2022, 5:25pm UTC](https://discourse.processing.org/t/loading-objs-with-callbacks/36066/2 "2022-04-01T17:25:56Z")

</div>

> [@Damdada](#):
>
> … that the images and OBJs order is different every time I load the sketch.

> [@Guidelines—Asking Questions](https://discourse.processing.org/t/guidelines-asking-questions/2147#is-your-post-formatted-8):
>
> Summary (TL;DR) Ask complete questions to get better answers! Be specific. For example: I want to load an image. I tried using createImg() , and I expected the image to be on canvas, but what happened instead was the image showing up below the canvas. Isolate your problem and work in small steps. Share only the code directly related to your problem if it is part of a bigger project, and if something isn’t working, try the smallest code that could do the thing you want. Can we run your code to …

B/c file operations in JS are asynchronous we can’t control the order they’re finished loading.

Also we don’t control what arguments are passed to a callback b/c they’re pre-determined by the caller.

Otherwise you could easily pass the index to be used for each loaded file.

However JS had a hidden hack gem which can create a clone of a function w/ modified context `this` and/or pre-filled parameters in addition to regular passed arguments:

> **[Function.prototype.bind() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#partially_applied_functions)**
>
> The bind() method of Function instances creates a new function that, when called, calls this function with its this keyword set to the provided value, and a given sequence of arguments preceding any provided when the new function is called.

Let’s take for example your **loadObjectElement()** function which invokes p5js **loadModel()** passing **objectLoaded()** as its callback:

```javascript
'use strict';

const
  ASSETS = 8,
  TOTAL = ASSETS << 1, // 16

  FOLDER = 'assets/',
  OBJ_EXT = '.obj',
  IMG_EXT = '.png',

  objects = Array(ASSETS).fill(),
  images = Array(ASSETS).fill();

var
  loading = true,
  objCounter = 0,
  imgCounter = 0;

function setup() {
  // blah, blah, blah...

  for (var i = 0; i++ < ASSETS; ) {
    loadObj(FOLDER + i + OBJ_EXT, i - 1);
    loadImg(FOLDER + i + IMG_EXT, i - 1);
  }
}

function draw() {
  if (loading) return;

  // blah, blah, blah...
}

function loadObj(filename, index) {
  loadModel(filename, true, objectLoaded.bind(null, index));
}

function objectLoaded(idx, obj) {
  objects[idx] = obj;
  if (++objCounter + imgCounter == TOTAL) loading = false;
}

function loadImg(filename, index) {
  loadImage(filename, imageLoaded.bind(null, index));
}

function imageLoaded(idx, img) {
  images[idx] = img;
  if (++imgCounter + objCounter == TOTAL) loading = false;
}

```

By passing a **bind()** callback to a loading function, we can force any number of preceding parameters to be filled w/ pre-determined arguments in addition to the caller’s sent arguments.

We already know the loading caller sends 1 argument to its callback, which is the loaded asset itself.

That’s why your **objectLoaded()** callback has 1 parameter named _object_:

> [@Damdada](#):
>
> function objectLoaded(object) {

In my “hacked” version I’ve added 1 extra parameter which comes before the regular parameter:

```javascript
function objectLoaded(idx, obj) {
  objects[idx] = obj;
  if (++objCounter + imgCounter == TOTAL) loading = false;
}

```

That extra parameter is gonna be filled w/ the _index_ value I’ve passed to **bind()**:

```javascript
function loadObj(filename, index) {
  loadModel(filename, true, objectLoaded.bind(null, index));
}

```

And that’s the hacked trick!

BtW, the code gets smaller & less complex if you instead just use [**preload()**](https://p5js.org/reference/#/p5/preload) to load your assets:

```auto
'use strict';

const
  ASSETS = 8,
  FOLDER = 'assets/',
  OBJ_EXT = '.obj',
  IMG_EXT = '.png',

  objects = Array(ASSETS).fill(),
  images = Array(ASSETS).fill();

function preload() {
  for (var i = 0; i++ < ASSETS; ) {
    loadObj(FOLDER + i + OBJ_EXT, i - 1);
    loadImg(FOLDER + i + IMG_EXT, i - 1);
  }
}

function loadObj(filename, index) {
  loadModel(filename, true, objectLoaded.bind(null, index));
}

function objectLoaded(idx, obj) {
  objects[idx] = obj;
}

function loadImg(filename, index) {
  loadImage(filename, imageLoaded.bind(null, index));
}

function imageLoaded(idx, img) {
  images[idx] = img;
}

```

---

_[View the full topic](https://discourse.processing.org/t/loading-objs-with-callbacks/36066)._
