1
const utterances = ['utt01', 'utt02', 'utt03']
const analysis = ['try+ing', 'climb+ing', 'swimm+ing']
const translation = ['trying', 'climbing', 'swimming']
let utteranceIndex = 0;
loadUtterance(utterances[utteranceIndex]);

function loadUtterance(utterance) {
  audio.src = `audio/${utterance}.mp3`;
  subtitle.innerText = utterance;
  translation.innerText = translation;
}

This is meant to be an exercise for studying a foreign text. I want to

  1. load and play the first utterance in the array;
  2. display the transcription (subtitle) of the utterance;
  3. Display the English translation. Then play the next utterance.

I have added the "analysis" array to help visualize what I am trying to do. Eventually I'd like to display the translation (and the analysis) only after an eventListener (the student's request with a click).

Problem: the translation items do not load with this script. I am a long retired linguist looking for some guidance. Thank you.

4
  • translation is an array, it has no innerText property Commented Jan 4, 2022 at 1:22
  • 2
    Tony, good question! I think you need to look at your function. You’re passing in one parameter (a single “utterance” that you’re selecting by using an array index), but in that function, you’re also expecting a “translation.” The problem appears to be that you’re not passing in a corresponding “translation” for the “utterance” - there are a couple different approaches you could take: Pass in multiple parameters, use a data structure different than an array of strings, such as an array of objects that have multiple properties. Commented Jan 4, 2022 at 1:26
  • @TonyM ... could the OP also consider accepting the answer which was the most helpful in answering the OP's question? Commented Jan 7, 2022 at 12:13
  • I'm studying the suggestions. What is OP? Should I select the most helpful answer asap? Thank you. Commented Jan 8, 2022 at 17:06

3 Answers 3

2

A feasible approach could be build around a generator which was created by a generator function and does yield an utterance item compound which gets created from the next/current index of all three initially provided arrays ...

function *createUtteranceItemGenerator(
  utteranceArray,
  analysisArray,
  translationArray,
  filesArray,
) {
  let name, idx = -1;

  // as long as an `utteranceArray` item exists ...
  while (name = utteranceArray[++idx]) {
    // ... create and yield an utterance item compound.
    yield {
      name,
      analysis: analysisArray[idx],
      translation: translationArray[idx],
      url: filesArray[idx]
    };
  } 
}

function renderNextUtteranceItem(item, elmNodes) {
  const { name, analysis, translation, url } = item;
  const { audio, label, caption } = elmNodes;

  console.log({ item });

  audio && (audio.src = url);
  // audio && (audio.src = `audio/${ name }.mp3`);

  label && (label.textContent = analysis);
  caption && (caption.textContent = translation);
}
function handleNextUtteranceItem(generator, elmNodes) {
  const item = generator.next();

  if (item.done === false) {
    renderNextUtteranceItem(item.value, elmNodes);  
  }
}

function init(config) {
  const elmFigure = document.querySelector('figure');
  const elmButton = elmFigure?.querySelector('button');

  if (elmButton) {
    const { utterances, analysis, translation, files } = config;
    const generator =
      createUtteranceItemGenerator(utterances, analysis, translation, files);

    elmButton
      .addEventListener(
        'click',
        (/* evt */) => handleNextUtteranceItem(generator, {
          audio: elmFigure.querySelector('audio'),
          label: elmFigure.querySelector('label'),
          caption: elmFigure.querySelector('figcaption'),
        }),
      );
  }
}

const files = [
  'https://freesound.org/data/previews/46/46989_514283-lq.mp3',
  'https://freesound.org/data/previews/46/46990_514283-lq.mp3',
  'https://freesound.org/data/previews/46/46991_514283-lq.mp3'
];
const utterances = ['utt01', 'utt02', 'utt03'];
const analysis = ['try+ing', 'climb+ing', 'swimm+ing'];
const translation = ['trying', 'climbing', 'swimming'];

init({ utterances, analysis, translation, files });
* { margin: 0; padding: 0; }
figure button { display: block; margin-bottom: 5px; }
figure label  { display: block; }

.as-console-wrapper {
  left: auto!important;
  width: 51%;
  min-height: 100%!important;
}
<figure class="utterance">
  <button>Next Utterance</button>

  <label></label>
  <figcaption></figcaption>

  <audio src="" controls autoplay></audio>
</figure>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. I'll be working more on this.
0

I have managed to make it work as follows (see above for the const):

function loadUtterance(utterance){
audio.src = audio/${utterance}.mp3;
var x = utteranceIndex;
document.getElementById("subtitle").innerText = subtitle[x];
} 

Thank you for the comments which gave me more ideas.

Comments

-1

Based on your description, there might be different reasons:

if you intend to display the whole array of translation/analysis, the problem is translation.innerText is actually operating the array you declared above instead of the html element, so if your html element that you want to show translation in's id is "translation", simply change your function to below should fix your problem:

function loadUtterance(utterance) {
   audio.src = `audio/${utterance}.mp3`;
   subtitle.innerText = utterance;
   document.getElementById("translation").innerText = translation;
}

Or if you want to display only the translation/analysis with the same utteranceIndex, then the function in your code seems in lack of couple input parameters (translation, analysis), Try the code below:

const utterances = ['utt01', 'utt02', 'utt03']
const analysis = ['try+ing', 'climb+ing', 'swimm+ing']
const translation = ['trying', 'climbing', 'swimming']
let utteranceIndex = 0;
loadUtterance(utterances[utteranceIndex], translation[utteranceIndex], analysis[utteranceIndex]);

function loadUtterance(selectedUtterance, selectedTranslation, selectedAnalysis) {
   audio.src = `audio/${selectedUtterance}.mp3`;
   subtitle.innerText = selectedUtterance;
   document.getElementById("translation").innerText = selectedTranslation;
   // analysis.innerText = selectedAnalysis;
}

1 Comment

Thank you very much. I follow what you wrote... will act.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.