onfinish on global soundmanager object - javascript

I would like to launch a function at the end of my sound, this code works :
var mysound;
var next = function(){
alert('end');
};
soundManager.onready(function () {
mysound = soundManager.createSound({
id:'foo',
url:'http://soundbible.com/grab.php?id=2077&type=mp3'
})
mysound.play({onfinish:next});
// change to this
// mysound.play();
});
// in another .js
// mysound.onfinish(next) // doesn't work
// mysound.prototype.options.onfinish = next // doesn't work
I would like to do something like I comment.
code on jsfiddle

The problem is that mysound tries to assign the onfinish before it's set to the correct value.
var mysound;
var next = function(){
alert('end');
};
function importedFromOtherFile( mysound ) {
mySound.onfinish(next);
}
soundManager.onready(function () {
mysound = soundManager.createSound({
id:'foo',
url:'http://soundbible.com/grab.php?id=2077&type=mp3'
})
mysound.play({onfinish:next});
// change to this
functionImportedFromOtherFile(mysound);
});
if you want it to be in a different file, see if you can give it a call back or throw an even with mysound after it's set

Related

How do I get a value back from a custom dojo module?

I'm working through the process of modulization on an app that I have written. This works with spatial location
I'm using an event to query for the user's lat / lon position for use inside the application. My calling snippet is below (button click starts it up)
<script>
require([
'dojo/dom',
'dojo/_base/array',
'demo/testModule',
'esri/SpatialReference',
'esri/geometry/Point'
], function (
dom,
arrayUtils,
testModule,
SpatialReference,
Point
) {
//Here is the button click listener
$('#whereAmIButton').click(function () {
var spatialRef = new esri.SpatialReference({ 'wkid': 4326 });
//variable I want to set to a returned geometry.
var myGeom;
//This runs but I'm missing the boat on the return of a value
testModule.findUserLocPT(spatialRef);
//var myModule = new testModule(); //not a constructor
});
});
</script>
Here is the custom module. It logs the information to the console for the user's location. But I want to return the value for setting the 'myGeom' variable.
define(['dojo/_base/declare','dojo/_base/lang','dojo/dom',
'esri/geometry/Point','esri/SpatialReference'], function (
declare, lang, dom, Point, SpatialReference) {
return {
findUserLocPT: function (spatialRef) {
var geom;
var location_timeout = setTimeout("geolocFail()", 5000);
navigator.geolocation.getCurrentPosition(function (position) {
clearTimeout(location_timeout);
var lat = position.coords.latitude;
var lon = position.coords.longitude;
setTimeout(function () {
geom = new Point(lon, lat, spatialRef);
//console.log writes out the geom but that isnt what I am after
console.log(geom);
//I want to return this value
return geom;
}, 500);
});
function geolocFail() {
console.log("GeoLocation Failure");
}
}
}//end of the return
});
Any help would be welcome. I can by reference back change textual/html values on the document but am not getting things back as a variable.
Andy
Ok, I don't know if this is the 'best' answer but I have one now.
I added a global variable inside the 'test.html' page
<script>
var theGeom; //This is the variable
require([
'dojo/dom',
here is where I am setting the value of this variable for use in the original dojo 'require' code block. This is coming from the 'testModule.js'
setTimeout(function () {
geom = new Point(lon, lat, spatialRef);
theGeom = geom; //Here is the feedback of the value to the global variable.
return myGeom;
}, 500);
$('#whereAmIButton').click(function () {
var spatialRef = new esri.SpatialReference({'wkid':4326});
testModule.findUserLocPT(spatialRef);
setTimeout(function () {
console.log(theGeom); //here is the value set and ready to use
},2000);
});
I'm not sure if this is the best way. If you have something better please let me know.
Andy

Meteor JS: obscene amount of data loaded in loop

I have an app that loads a Jobs collection
Deps.autorun(function(){
var onet = Session.get('currentIndustryOnet');
var city_id = Session.get('currentMapArea');
jobsSubscription = Meteor.subscribe('jobs', onet, city_id);
console.log(onet);
if(jobsSubscription.ready) {
Session.set('jobCount', Jobs.find().count());
}
});
Template.selector.events({
'click div.select-block ul.dropdown-menu li': function(e) {
var selectedIndex = $(e.currentTarget).attr("rel");
var val = $('select#industryPicker option:eq(' + selectedIndex + ')').attr('value');
var oldVal = Session.get('currentIndustryOnet');
if(val != oldVal) {
Session.set('jobsLoaded', false);
Session.set('currentIndustryOnet', val);
}
}
});
The console logs 20+ values for what the var onet is. It appears that Meteor.autorun doesn't run just once. Is this normal? If not, how do I fix this to only run once?
Updated:
Jobs = new Meteor.Collection('jobs');
Cities = new Meteor.Collection('cities');
Pagination.style('bootstrap');
Session.setDefault('jobCount', null);
Session.setDefault('jobsLoaded', false);
Meteor.subscribe('cities');
Session.set('jobCount', Jobs.find().count());
Deps.autorun(function(){
var onet = Session.get('currentIndustryOnet');
var city_id = Session.get('currentMapArea');
Meteor.subscribe('jobs', onet, city_id, function onReady(){
Session.set('jobsLoaded', true);
});
Session.set('jobCount', Jobs.find().count());
});
function plotCities() {
console.log("CITIES PLOTTING");
// var jobs = Jobs.find().fetch();
// var addresses = _.chain(jobs)
// .countBy('address')
// .pairs()
// .sortBy(function(j) {return -j[1];})
// .map(function(j) {return j[0];})
// .slice(0, 50)
// .value();
// gmaps.clearMap();
// $.each(_.uniq(addresses), function(k, v){
// var addr = v.split(', ');
// Meteor.call('getCity', addr[0].toUpperCase(), addr[1], function(error, city){
// if(city) {
// var opts = {};
// opts.lng = city.loc[1];
// opts.lat = city.loc[0];
// opts.population = city.pop;
// opts._id = city._id;
// gmaps.addMarker(opts);
// }
// });
// })
}
Template.list.jobs = function() {
plotCities();
return Pagination.collection(Jobs.find({}).fetch());
}
The console.log('CITIES PLOTTING') gets called around 8 times the first time the page loads and then if I switch the Sessioned onet, and the jobs reloads the data, the call is 30+ times
Update 2:
Here is my code:
Session.set('jobsLoaded', false);
Meteor.subscribe('cities');
Session.set('jobCount', Jobs.find().count());
Deps.autorun(function(){
var onet = Session.get('currentIndustryOnet');
var city_id = Session.get('currentMapArea');
Meteor.subscribe('jobs', onet, city_id, function onReady(){
Session.set('jobsLoaded', true);
});
Session.set('jobCount', Jobs.find().count());
});
function plotCities() {
var jobs = Jobs.find().fetch();
var addresses = _.chain(jobs)
.countBy('address')
.pairs()
.sortBy(function(j) {return -j[1];})
.map(function(j) {return j[0];})
.slice(0, 50)
.value();
gmaps.clearMap();
$.each(_.uniq(addresses), function(k, v){
var addr = v.split(', ');
Meteor.call('getCity', addr[0].toUpperCase(), addr[1], function(error, city){
if(city) {
var opts = {};
opts.lng = city.loc[1];
opts.lat = city.loc[0];
opts.population = city.pop;
opts._id = city._id;
gmaps.addMarker(opts);
}
});
})
}
Template.list.jobs = function() {
if(Session.equals('jobsLoaded', true)) {
console.log("LOADED PLOT");
plotCities();
}
return Pagination.collection(Jobs.find({}).fetch());
}
When console.log("LOADED PLOT") is called... the first time it loads 8 times, the second, almost 40...
Deps.autorun rerun whenever a reactive item used inside is updated. You've got three such items in your function: two session variables and .ready() handle. Most probably the last one is causing the multiple rerun. If you're certain that the session variables were not touched during that time, that's the only option.
While I'm not certain about this, .ready() might be invalidated each time a new item is pulled up in the subscription channel. So having this check inside your autorun would result in several initial reruns as the first batch of data is pulled.
Move that check outside of autorun (it's possible as the subscription is visible from outside) and the problem should be solved.
Ah, now it's something else: you're calling plotCities from Template.list.jobs, which is also reactive and get rerun each time something in Jobs.find({}) changes – so again, each time a new initial item is loaded.
You've got a session variable in which you mark that your subscription is ready. Use it to filter the call:
Template.list.jobs = function() {
if(Session.equals('jobsLoaded', true)) plotCities();
return Pagination.collection(Jobs.find({}).fetch());
}

Start object from setInterval?

I have the following reconnect method for Sockjs which almost is fully working:
(function() {
// Initialize the socket & handlers
var connectToServer = function() {
var warbleSocket = new SockJS('http://url.com:5555/warble');
warbleSocket.onopen = function() {
clearInterval(connectRetry);
$('.connect-status')
.removeClass('disconnected')
.addClass('connected')
.text('Connected');
};
warbleSocket.onmessage = function(e) {
$('#warble-msg').text(e.data);
};
warbleSocket.onclose = function() {
clearInterval(connectRetry);
connectRetry = setInterval(connectToServer, 1000);
$('.connect-status')
.removeClass('connected')
.addClass('disconnected')
.text('Disconnected');
};
// Connect the text field to the socket
$('.msg-sender').off('input').on('input', function() {
warbleSocket.send($('.msg-sender input').val());
});
function send(a) {
warbleSocket.send(a);
}
return {
send: send
};
}();
var connectRetry = setInterval(connectToServer, 1000);
})();
The error i am getting is when its trying to reconnect.
Error is:
SyntaxError: missing ] after element list
at this line:
connectRetry = setInterval(connectToServer, 1000);
Any ideas what im doing wrong here?
Your connectToServer variable is not a function, it's an object with a property send that is a function, so it doesn't make sense to say setInterval(connectToServer, 1000). Try this instead:
setInterval(connectToServer.send, 1000);
Why don't you simplify things a bit?
I would put connection stuff inside a specific function and call it from setInterval().
Something like this (use with care since I'm not testing this code, ok?):
(function() {
// Initialize the socket & handlers
var connectToServer = function() {
var warbleSocket;
function connect() {
warbleSocket = new SockJS('http://url.com:5555/warble');
warbleSocket.onopen = function() {
// ...
};
warbleSocket.onmessage = function(e) {
// ...
};
warbleSocket.onclose = function() {
// ...
}
// Connect the text field to the socket
$('.msg-sender').off('input').on('input', function() {
warbleSocket.send($('.msg-sender input').val());
});
function send(a) {
warbleSocket.send(a);
}
return {
send: send
};
}();
// you probably will need to call the first connection
connectToServer();
// and than set connection retry
var connectRetry = setInterval(connectToServer.connect, 1000);
})();
I hope it helps you.
Regards,
Heleno

Put data from a IndexedDB data base in a variable

I'm trying to put the data read from the database in a variable. I have tryed many things, including a callback function, but nothing looks to work when the process is outside of the "opencursor().onsuccess" function scope.
The "Alert 1" show the result correctly, but "Alert 2" and "Alert 3" don't.
I'm calling the 'main()' function from HTML code.
I'm really frustrated, because I have been mining internet searching for the solution without any positive result.
Can anybody help me, please?
Thanks a lot.
var data=[];
function kkeyget(t1, db_name, db_version)
{
var request = indexedDB.open(db_name, db_version);
request.onerror=function()
{
alert("Error");
}
request.onsuccess=function(event)
{
var db=this.result;
var trans = db.transaction(t1, "readonly");
var objectStore = trans.objectStore(t1);
objectStore.openCursor().onsuccess = function(event)
{
var cursor = event.target.result;
if (cursor)
{
data.push(cursor.value);
//Alert 1:
alert(data[0].id);
cursor.continue();
}
else alert("No more entries!");
};
}
//Alert 2:
alert(data[0].id);
}
function main()
{
kkeyget("agenda", "example_db", 1);
//Alert 3:
alert(data[0].id);
}
Correct. Because all indexedDB actions are asynchronous, your code will run:
alert 2 // undefined
alert 3 // undefined
alert 1 // correct
In order to get this closer to a synchronous action, you need to have it call a new function after it's done collecting data. Where your alert("No more entries!") is.
Instead of trying to return a key, pass in a custom callback function that takes the retrieved key as its argument.
// Your old function slightly modified
function kkeyget(t1, db_name, db_version, callback, fallback) {
// ... yada yada yada
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if(cursor) {
callback(cursor.value);
} else {
fallback();
}
}
}
// Now in your calling code:
kkeyget('a','b',1, function(id) {
// Do something with the 'id'
// here in this anonymous function callback
}, function() {
// Do something here to indicate no match
});

jquery my done callback gets only called one time i dont get why

/**
* Downloads the fingerprint preview data
*/
this.fetchFingerprintPreviews = function (url) {
var that = this;
var dfd = jQuery.Deferred();
jQuery.get(url)
.done(function (resp) {
var linkNodes = conn.getLinksViaRelation(resp,
'http://ws.bdr.de/webhd/hdcap/rels/finger-preview/');
jQuery(linkNodes).each(function () {
var link = jQuery(this);
var fpIndex = link.prev("index, bdr\\:index").html();
var fpType = link.attr('type');
jQuery.get(link.attr('href'), {"encoding":"base64"}, null, "text")
.done(function (imageDataBase64) {
fingerprintPreview[fpIndex] = {};
fingerprintPreview[fpIndex].imageData = imageDataBase64;
fingerprintPreview[fpIndex].type = fpType;
console.log(fingerprintPreview);
if (Object.keys(fingerprintPreview).length ==
Object.keys(linkNodes).length) {
dfd.resolve();
}
});
});
});
return dfd;
}
a new version added which makes use of lexical local variables. still not working.
m a bit lost at the moment...
also added a log statement which gets called only one time.
i would expect the log to get called two times.
any ideas?
The problem isn't that your done callback is called once, but that you change the same fingerprintPreview each time it is called because that has the value of end of loop when the callbaks are called.
The solution is to not reuse this externally declared variable but a new one, declared in the function you give to each :
jQuery(linkNodes).each(function () {
var link = jQuery(this);
var fpIndex = link.prev("index, bdr\\:index").html();
var fpType = link.attr('type');
jQuery.get(link.attr('href'), {"encoding":"base64"}, null, "text")
.done(function (imageDataBase64) {
fingerprintPreview[fpIndex] = {};
fingerprintPreview[fpIndex].imageData = imageDataBase64;
fingerprintPreview[fpIndex].type = fpType;
if (Object.keys(fingerprintPreview).length == Object.keys(linkNodes).length) {
alert("foo");
}
});
});
i found out what the problem was. dystroys answer is correct but was not adressing my original problem. so the thing is that when i have a firebug breakpoint in my done function callback it will be called only one time. so having breakpoints set with firebug can lead to uninterpreted js code... ffs!

Categories

Resources