Kemel Zaidan
Kemel Zaidan

Reputation: 613

Wait for data on Blaze when using ReactiveVar on Meteor

I'm facing a weird problem on a Blaze template in Meteor.js. The following template is rendered four times (with an {{#each}} operator)

<template name="circle">
  <div class="col-md-6">
    <div class="circle-container">
      <div class="circle {{option}}" style="border: 9px solid {{color}}">
        <div class="circle-text {{option}}" style="color:{{color}}">{{name}}</div>
      </div>
    </div>
  </div>
</template>

The data is passed to the template as a ReactiveVar that holds an array of objects. Each object renders a circle on the template. The logic to generate this data sits below:

const colorSet = ['red','gold','blue','green','orange','turquoise','wheat','fuchsia','purple'];
const colorNames = ['VERMELHO','AMARELO','AZUL','VERDE','LARANJA','TURQUESA','BEGE','ROSA','ROXO'];

var limit = colorSet.length;

// helper functions
function getRandomPosition() {
  return Math.floor(Math.random() * (limit + 1));
}

function getRightColor() {
  let position = getRandomPosition();
  let rightColor = {
    color: colorSet[position],
    name: colorNames[position],
    right: 'right-option',
  };
  return rightColor;
}

function getWrongColor() {
  let position1 = getRandomPosition();
  let position2 = getRandomPosition();
  while (position1 === position2) {
    position2 = getRandomPosition();
  }
  let wrongColor = {
    color: colorSet[position1],
    name: colorNames[position2]
  };
  return wrongColor;
}

function make4Circles() {
  let circles = [];
  circles.push(getRightColor());

  for (let i = 0; i < 3; i++) {
    circles.push(getWrongColor());
  }
  console.log('circles:', circles)
  return circles
}

////
// TEMPLATE HELPERS
///
Template.gameArea.onCreated(function () {
  this.circleArray = new ReactiveVar(make4Circles());
})


Template.gameArea.helpers({
  circles () => {
    return Template.instance().circleArray.get();
  }
})

The problem is that the page sometimes lacks data, what gives me the impression that the template is being rendered before the data is ready. Since blaze is reactive, I thought that this wasn't going to happen since tracker would know the data have changed and would re-render the template again. But the truth is that sometimes it lacks some data.

I have looked all over the documentation and I'm not sure if I'm facing some sort of bug or doing something wrong...

If anyone wants to run the code, it's on this github repo: https://github.com/kemelzaidan

Upvotes: 1

Views: 80

Answers (1)

ghybs
ghybs

Reputation: 53185

I suspect the issue does not come from Blaze but from your data generation algorithm.

Does your console.log('circles:', circles) always output correct data?

The Math.floor(Math.random() * (limit + 1)) seems to sometimes generate an integer outside your array index range.

In your case, limit would be 9 (i.e. 9 items in your colorSet array, which therefore has indices from 0 to 8), so limit + 1 is 10.

Then Math.floor on Math.random() * 10 would sometimes give 9, which is outside your array range.

=> just removing that +1 should solve your issue.

Upvotes: 1

Related Questions