“Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.”
I’m sorry if this is a stupid question, but I am just getting back into Meteor and JS after taking over a year off and I was pretty new back then anyways. I’m a long time lurker, because usually I can find an answer for things through Google.
Unfortunately, this seems to be over my head. The more I read about Fibers, Threads, Promises, Asynchronous, Synchronous, aSync, bindEnviroment, callbacks, etc… the more confused I get.
I am trying to retrieve data from an API and store it in a collection for use in my app, then update that data every minute. Each API call returns about 300 to 400 objects, so I guess that may be why I am getting an error… that is a lot of data to manipulate in a minute. I also created a few arrays of data that is updated every five minutes, every hour, and every day for the purpose of adding some graphs to my app. I am not sure what part of this is not running in a Fiber, so I’m not sure where to even start.
Can anyone give me any idea what I’m doing wrong? Any hints as to how to make it more efficient would be much appreciated too!! I am trying to write a complicated app for a beginner, but I guess you have to learn somehow!
This file is in my server folder and I’m certain the error is contained in it, as this file is all I’ve worked on all day:
//retrieve data from API every 60 seconds
setInterval(function () {
//returns an array of objects
var response = HTTP.get('GET', 'https://api.coinmarketcap.com/v1/ticker/');
//iterate through each object
for (var i = 0; i < (response.data.length); i++) {
//assign each object's properties to a temp object, then import said object into MongoDB
var coin = {};
coin.id = response.data[i].id;
coin.name = response.data[i].name;
coin.symbol = response.data[i].symbol;
coin.rank = response.data[i].rank;
coin.priceUsd = response.data[i].price_usd;
coin.priceBtc = response.data[i].price_btc;
coin.volume24Hour = response.data[i]["24h_volume_usd"];
coin.marketCap = response.data[i].market_cap_usd;
coin.availableSupply = response.data[i].available_supply;
coin.totalSupply = response.data[i].total_supply;
coin.percentChange1Hour = response.data[i].percent_change_1h;
coin.percentChange24Hour = response.data[i].percent_change_24h;
coin.percentChange7Day = response.data[i].percent_change_7d;
coin.lastUpdated = response.data[i].last_updated;
coin.priceArray24H = [];
coin.priceArray7D = [];
coin.priceArrayAll = [];
coin.volumeArray24H = [];
coin.volumeArray7D = [];
coin.volumeArrayAll = [];
//See if the coin already has a document in the collection
if (Cryptos.findOne({
id: coin.id
}) == null) {
//Each number in the following arrays will be used as data points on a chart
//24H = 288 Data Points MAX (Updated every 5 minutes)
//7D = 168 Data Points MAX (Updated every hour)
//All = Unlimited Data Points (Updated every day)
//Setup arrays for charts and enter the first value
coin.priceArray24H.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.priceArray7D.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.priceArrayAll.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArray24H.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
coin.volumeArray7D.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
coin.volumeArrayAll.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
//Insert new coin document into collection, because the coin is not already there
Cryptos.insert(coin);
} else {
//Pull the arrays out of the collection to analyze or manipulate later
coin.priceArray24H = Cryptos.findOne({
id: coin.id
}, {
priceArray24H: true
});
coin.priceArray7D = Cryptos.findOne({
id: coin.id
}, {
priceArray7D: true
});
coin.priceArrayAll = Cryptos.findOne({
id: coin.id
}, {
priceArrayAll: true
});
coin.volumeArray24H = Cryptos.findOne({
id: coin.id
}, {
volumeArray24H: true
});
coin.volumeArray7D = Cryptos.findOne({
id: coin.id
}, {
volumeArray7D: true
});
coin.volumeArrayAll = Cryptos.findOne({
id: coin.id
}, {
volumeArrayAll: true
});
//24H Array Logic - 288 Data Points MAX (Updated every 5 minutes)
//If 5 minutes has gone by
var length24H = coin.priceArray24H.length() - 1;
if (coin.lastUpdated - (coin.priceArray24H[length24H].lastUpdated >= 300)) {
//If there's less than 288 price points in the array
if (coin.priceArray24H.length < 288) {
coin.priceArray24H.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArray24H.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
} else {
//If array is at the maximum amount of data points wanted,
//Then remove the first value add the updated value to the end
coin.priceArray24H.shift();
coin.priceArray24H.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArray24H.shift();
coin.volumeArray24H.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
}
}
//7Day Array Logic - 168 Data Pints MAX (Every hour)
//See if a hour has gone by since the last update
var length7D = coin.priceArray7D.length() - 1;
if (coin.lastUpdated - (coin.priceArray7D[length7D].lastUpdated >= 3600)) {
if (coin.priceArray7D.length < 168) {
//If array has less than 168 data points
//Then add values to the end of the arrays
coin.priceArray7D.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArray7D.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
} else {
//If array is at the maximum amount of data points wanted,
//Then remove the first value add the updated value to the end
coin.priceArray7D.shift();
coin.priceArray7D.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArray7D.shift();
coin.volumeArray7D.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
}
}
//All Array Logic - Unlimited Data Points (Updated Every 24H)
//See if a day has gone by since the last update
if (coin.lastUpdated - (coin.priceArrayAll[coin.priceArrayAll.length() - 1].lastUpdated >= 86400)) {
//Add to the end of the array if 24 hours have gone by since the last update
coin.priceArrayAll.push({
price: coin.priceUsd,
timestamp: coin.lastUpdated
});
coin.volumeArrayAll.push({
volume: coin.volume24Hour,
timestamp: coin.lastUpdated
});
}
//Update the coin's document since it is already in the collection
Cryptos.update({
id: coin.id
}, {
$set: {
rank: coin.rank,
priceUsd: coin.priceUsd,
priceBtc: coin.priceBtc,
volume24Hour: coin.volume24Hour,
marketCap: coin.marketCap,
availableSupply: coin.availableSupply,
totalSupply: coin.totalSupply,
percentChange1Hour: coin.percentChange1Hour,
percentChange24Hour: coin.percentChange24Hour,
percentChange7Day: coin.percentChange7Day,
lastUpdated: coin.lastUpdated,
priceArray24H: coin.priceArray24H,
priceArray7D: coin.priceArray7D,
priceArrayAll: coin.priceArrayAll,
volumeArray24H: coin.volumeArray24H,
volumeArray7D: coin.volumeArray7D,
volumeArrayAll: coin.volumeArrayAll
}
});
}
}
}, 60 * 1000);