# 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:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Damdada](https://avatars.discourse-cdn.com/v4/letter/d/cdc98d/32.png) [@Damdada](https://discourse.processing.org/u/Damdada)\
**Post date:** [April 1, 2022, 12:05pm UTC](https://discourse.processing.org/t/loading-objs-with-callbacks/36066/1 "2022-04-01T12:05:09Z")

</div>

Hi,  
im trying to load multiple OBJs and Images with callbacks into my sketch. The loading works fine but the Problem is that the Images and OBJs order is diffrent evreytime i load the sketch. So the images i take for the texture dont fit with the OBJs.  
Heres my code and thx 4 ur help:)

```Javascript
let x = 1;
var objects = [];
var images = [];
var totalObjects = 8;
var totalImages = 8;
var counterObject = 0;
var counterImage = 0;
var loadingObject = false;
var loadingImage = false;
var loading = true;

function loadObjectElement(filename) {
  loadModel(filename, true, objectLoaded);

  function objectLoaded(object) {
    console.log(filename);
    append(objects, object);
    counterObject++;
    if (counterObject == totalObjects) {
      loadingObject = true;
    }
  }
}

function loadImageElement(filename) {
  loadImage(filename, imageLoaded);

  function imageLoaded(image) {
    console.log(filename);
    append(images, image);
    counterImage++;
    if (counterImage == totalImages) {
      loadingImage = true;
    }
  }
}

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);

  for (let i = 1; i <= 8; i++) {
    loadObjectElement("assets/" + i + ".obj");
  }

  for (let i = 1; i <= 8; i++) {
    loadImageElement("assets/" + i + ".png");
  }
}

function draw() {
  if ((loadingImage) && (loadingObject)) {
    loading = false;
  }

  if (!loading) {
    texture(images[x])
    scale(3);
    model(objects[x]);
  }
}

```

---

<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;
}

```

---

<div class="post-metadata">

**Author:** ![Damdada](https://avatars.discourse-cdn.com/v4/letter/d/cdc98d/32.png) [@Damdada](https://discourse.processing.org/u/Damdada)\
**Post date:** [April 1, 2022, 7:40pm UTC](https://discourse.processing.org/t/loading-objs-with-callbacks/36066/4 "2022-04-01T19:40:05Z")

</div>

Thanks a lot works perfect now!🙂
