Elliot Morrison-Reed Elliot Morrison-Reed - 9 months ago 32
Javascript Question

How to get Primitive Array from ES6 Promises

I am trying to load glsl scripts as strings using the ES6 Promise and Fetch APIs. I thought I had a pretty elegant solution for getting the vertex and fragment shaders and creating a new programInfo with twgl.js

Promise.all([fetch(vert_url),fetch(frag_url))])
.then((responses) => responses.map((response) => response.text()))
.then((sources) => this.programInfo = twgl.createProgramInfo(gl, sources));


The problem is that it seems that response.text() is returning a Promise rather than a raw string. Inside
twgl.createProgramInfo()
it runs sources through a map, and then attempts to run indexOf on the results.

function createProgramInfo(gl, shaderSources, ...) {
...
shaderSources = shaderSources.map(function (source) {
// Lets assume if there is no \n it's an id
if (source.indexOf("\n") < 0) {
...


Chrome throws a javascript error on the final line there:

Uncaught (in promise) TypeError: source.indexOf is not a function


I can't seem to figure out how to turn
sources
into real strings. Anybody have an idea how to get this working?

Note: This is actually in a React app created using create-react-app, that means webpack and babel are being used to transpile this from jsx.

Answer Source

In order to convert an array of promises into a promise of an array, use Promise.all:

Promise.all([fetch(vert_url),fetch(frag_url))])
       .then(responses => Promise.all(responses.map(response => response.text())))
       .then(sources => this.programInfo = twgl.createProgramInfo(gl, sources));

Promise#then will evaluate the promise you return in the callback from Promise.all, and will make the next call to .then evaluate to the array of sources, which is what your code expects.