WebMidi.js does not recognize my midi controller - javascript

I am trying to use the WebMidi.js library to read inputs from my midi controller.
When I try to log the inputs or outputs, it comes up as an empty array. Here is my code:
WebMidi.enable(function (err) {
if (err) {
console.log("WebMidi could not be enabled.", err);
} else {
console.log("WebMidi enabled!");
console.log(WebMidi.inputs);
console.log(WebMidi.outputs);
}
});
The log I get is 2 empty arrays for input and output.
And here are pictures of my Midi Studio setup in Mac. I'm not sure if I'm supposed to do some extra configuration here to make my Roland A-PRO show up as an input/output. I see that it is grayed out which makes me think it must need some extra configuration.
The controller works when I run it through Ableton, however.

example for vanilla JS
function midiOnStateChange(event) {
console.log('midiOnStateChange', event);
}
function midiOnMIDImessage(event) {
console.log('midiOnMIDImessage', event);
}
function requestMIDIAccessSuccess(midi) {
var inputs = midi.inputs.values();
for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
console.log('midi input', input);
input.value.onmidimessage = midiOnMIDImessage;
}
midi.onstatechange = midiOnStateChange;
}
navigator.requestMIDIAccess().then(requestMIDIAccessSuccess);
run example in browser
https://surikov.github.io/webaudiofont/examples/midikey.html

Related

Gulp- Make sure file has comments in the beginning

I have multiple javascript files in a folder and I want to make sure that every file has comment in the beginning (that will explain the summary of file).
/*
This file will......
*/
function test () {
....
}
So is this possible using gulp-contains or something else?
I think this would be enough just to make sure if start of a file is the comment initial characters (/*)
gulp.src('./file.js')
.pipe(map(function(file, callback) {
var startWithComment = file.contents.toString().replace(/\n|\r/g, "").trim().startsWith("/*");
if (startWithComment){
// DO YOUR CHORES
}
}))
Another approach is to split the initial text to make sure if it is a valid multi-line comment.
function startsWithValidMultiLineComment(str){
try{
return str.replace(/\n|\r/g, "").trim().split("/*")[1].split("*/")[1].length > 0
} catch (e){
return false;
}
}
Following this approach str.split("/*")[1].split("*/")[0] would be your comment text
By using the regex provided by #Sajjad in previous answer. I have managed to achieve my goal. I have used gulp-if and gulp-fail instead (I find it more flexible).
Here is how I do that:
var condition = function (file) {
sFile = require('path').parse(file.path).name;
var startWithComment = file.contents.toString().replace(/\n|\r/g, "").trim().startsWith("/*");
return (!startWithComment);
}
gulp.task('taskName',
function() {
gulp.src('files/*.js')
.pipe(gulpIf(condition, fail(function () {
var message = 'Some message';
return message;
})));
});

NodeJS infinite running terminal app with read from terminal

I am trying to create a terminal app that will run indefinitely and will have the ability to read from the terminal.
I tried to user the "readline" api but the app terminates without waiting for any input.
I added a "while(true)" loop but it seems that the thread gets stacked in the loop and does not respond to my input.
I need a series of random numbers.
To accomplice it I added an interval of 1000ms and the result was the same with while loop.
To summary I need to create an app that reads from the terminal and create random numbers on a given interval.
Any guidance will be appreciated.
Edit 1
Additional information I just thought to give you.
I tried to put either the readline call or the interval in a separate forked process but nothing changed.
Also I tried to use recursion for the readline.
Edit 2
Although I accepted #amangpt777`s answer I would like to give another problem that you might encounter.
I was calling my script like this 'clear | node ./script.js' on windows` powershell.
I believe that it was the pipe that was blocking my input.
I don't know if this can happen on linux, I haven't tested it.
I just add it here so you keep it in mind.
I am not sure what you are trying to accomplish here. But following code will take input from user using readline and will keep on storing the input in an array. Note that I have some commented code in this which can be uncommented if you want a publish subscriber model. Also that you will need to add more code to sanitize and validate your input. I hope you will get some pointers to achieve what you want with this:
var readline = require('readline');
//var redis = require('redis');
//let subscriber = redis.createClient();
//let publisher = redis.createClient();
let numEntered = [];
var r1 = readline.createInterface(
{
"input": process.stdin,
"output": process.stdout
}
);
// subscriber.subscribe('myFunc');
// subscriber.on('message', (channel, msg) => {
// //Your logic
// });
function printMyArr(){
console.log("Numbers entered till now: ", numEntered);
}
function askNumber(){
askQuestion('Next Number?\n')
.then(ans => {
handleAnswer(ans);
})
.catch(err => {
console.log(err);
})
}
function handleAnswer(inputNumber) {
if(inputNumber === 'e') {
console.log('Exiting!');
r1.close();
process.exit();
}
else {
numEntered.push(parseInt(inputNumber));
//publisher.publish('myFunc', parseInt(inputNumber));
// OR
printMyArr();
askNumber();
}
}
function askQuestion(q) {
return new Promise((resolve, reject) => {
r1.question(q, (ans) => {
return resolve(ans);
});
});
}
function init() {
askQuestion('Enter Stream. Press e and enter to end input stream!\n')
.then(ans => {
handleAnswer(ans);
})
.catch(err => {
console.log(err);
})
}
init();

Why aren't i successfully getting the embedded "if" in the second code section to do its job?

var checking_location = "none"
const getentitiesByType = (arr, type) => {
for (let i in arr) {
if (arr[i].type === type) {
checking_location = "exists"
return arr[i].entity
}
}
return null;
}
if (!meeting.location) {
if (checking_location != 'exists') {
rl.question('where is the location ', function(answer) {
// session.send("The location you gave:" answer);
rl.close();
session.send(answer)
// console.log(tryagain(answer, 'Calendar.Location'));
session.send(tryagain(answer, 'Calendar.Location'));
});
}
} else {
next();
}
What i'm trying to do here is to have a loop in the if (!meeting.location) if checking_location stays equal to none. Basically i want to check if a certain Json field exists, if it doesn't i want to keep asking the question in rl.question.My issues is that the code is only working the first time, then even if i give another input not containing the required field i don't get that question.Also note that this is not the entire code but it's more than enough to understand the possible issue spots in my implementation.
getentitiesByType needs to be called somewhere, simply assigning it to a variable will not make the function run: getentitiesByType(youArr, yourType).
Also, as a side note, instead of using string values for checking_location just rename the variable and use a boolean value. Ex: var hasLocation = false.

Create flash message when validation fails in KeystoneJS

I need to make flash error messages change according to the type of validation error. Right now it always says: Database error if one of my custom validations doesn't pass.
My custom validations happen in my model, and not in my controllers, so I am not sure how to traverse between the two.
Here is one of my custom validations:
User.schema.path('email').validate(function (value) {
if (validator.isEmpty(value) || validator.isEmail(value)) {
return true;
}
else {
return false;
}
});
The validation works perfectly, it's just the flash message that I want to change.
You can pass custom error messages to the validate function as well, just pair it with the function by wrapping it in an array, like this:
User.schema.path('email').validate([function (value) {
if (validator.isEmpty(value) || validator.isEmail(value)) {
return true;
}
else {
return false;
}
}, "WRONG!"]);

Inserting multiple values in Mysql using Nodejs and notifying user with a response

I am making a new webservice where i send a curl command with JSON and the JSON contains a array as
[{tempid:1,email:abc#123,address:asd},{tempid:2,email:abc#12345,address:asd45},{tempid:3,email:abc#1234,address:asd4}]
Now when i pass and insert the array in a mysql table tempid is just to show a mapping to the user to the contact id generated in the database as tempid:1 is now inserted and in database it has cid 120 , like this for tempid2 and 3 ,
But when i am trying to show the client the updated values it shows only one value , last last change not the whole updated Array. Its becuase of the async nature of the connection.querry function , so i need help in this , here is my webservice
contactadd webservice -->
for(var i=0;i<=request.body.contact.length-1;i++)
{
if(request.body.contact[i].tempid)
{ var ardata=new Array();
var o=request.body.contact[i];
pair=Object.keys(o).map(function(a){ return [a, o[a]] });
AM.addcontact(pair,request.session.user,request.body.contact.length,function(e,o){
if(!o)
{
response.send('something went wrong'+e);
}
else
{
//response.send(o);
}
});
}
}
Here is the update function in the database.js script -->
//ContactSync-addcontact module for database
exports.addcontact=function (arr,email,addnum,callback)
{
var counter=0;
var uid;
var data=new Array();
var showinsert=new Array();
var values=new Array();
var datatable=new Array();
var inserting=new Array();
var tempid=0;
connection.query('SELECT UID FROM user where email1="'+email.email+'"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
if(rows[0]!=undefined)
{
uid=rows[0]['UID'];
}
else
{
uid="no id in database";
}
}
});// get the UID of the inserting user
// make array of user provided data
for(var j=0;j<=arr.length-1;j++)
{
if(arr[j][0]!='tempid')
{
data.push(arr[j][0]);
}
else
{
tempid=arr[j][1];
}
}
connection.query('SELECT column_name FROM information_schema.columns where table_schema="webservice" AND table_name="usercontacts"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
for(var i=0;i<=rows.length-1;i++)
{
datatable.push(rows[i]['column_name']);
}
}
for(var k=0;k<=datatable.length-1;k++)
{
if(inArray(data[k],datatable))
{
inserting.push(data[k]);
}
}
if(inserting.length>0)
{
for(var z=0;z<=arr.length-1;z++)
{
if(inArray(arr[z][0],inserting))
{
values.push('"'+arr[z][1]+'"');
}
}
// Insert tempid values and data in the usercontacts table with inserting and values
connection.query('INSERT INTO usercontacts (cid,uid,'+inserting+') VALUES("","'+uid+'",'+values+')',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
connection.query('SELECT * FROM usercontacts WHERE uid="'+uid+'" ORDER BY cid DESC LIMIT 0,'+addnum+'',function(err,rows,fields){
if(err)
{
throw err;
}
else
{ showinsert.push('temp-id: '+tempid+',cid:'+rows[0].cid+',uid:'+uid);
//for(var i=0;i<=inserting.length-1;i++)
forEach(inserting,function(row,index)
{
showinsert.push(inserting[index]+":"+values[index]);
counter+=1;
});
callback(null,showinsert);
}
});
}
});
//insertion finished
}
else
{
callback("Please Provide atleast one field to enter with tempid");
}
});
}
I just need to insert all the callback in a array which has been inserted and show user that array ,please help , completely stuck and then only i am trying StackOverflow.
Thank you for reading till the end BTW
I'm not sure what the specific problem is, but there are some problems with the code you've shared that will bite you sooner or later. One of these may be causing your problem.
Race conditions
If the query SELECT UID FROM user where email1= for any reason takes longer than the SELECT column_name FROM information_schema.columns just below it then you won't have a value for the variable uuid and your logic will fail. Remember that these calls are non-blocking, so you can't rely on one finishing before the other one unless they're nested or use another flow-control mechanism (As #Tracker points out, async is popular).
Catching edge cases
In the line below you're assigning a string value to the uid variable and then continuing to use that variable even though it now contains an error message.
uid="no id in database";
Doing that means that your code later on will have trouble reacting. Instead use a different variable, leave the uid = undefined or immediately return the callback with an error, e.g.
return callback(new Error("user not found"));
Reporting errors
Don't throw errors in Node unless you want to kill the process, e.g. dependency problems during server startup. It doesn't work like Java, async errors are not caught by try/catch and will kill your process or leave you in a state that's hard to reason about. Instead make the error object your first parameter to the callback and return it immediately, like this:
if ( err ) return callback(err);
Then in your client code you can always check the first parameter to see if there was a problem.
Security problem
As #Tracker mentioned, don't ever do the this:
connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...
If the value of the variable is passed through as "; drop table user; or similar then you're in trouble. Instead you can use node-mysql's build in escaping like this:
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
Whitelist
You're querying information_schema.columns in order to detect which fields are valid then inserting them into usercontacts. This is a clever trick, but increases a 3 query process to 4 queries, and raises questions if there are any fields that a user shouldn't be inserting data into. Using a column whitelist may seem like more code to maintain, but would actually be simpler than all the code required to match columns dynamically.
Arrays
I don't see the source for the function inArray() but it looks like it does the same as Array.prototype.indexOf() so it may be better to use that. e.g.
if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);
Every line of custom code you can delete is a line of code you don't have to maintain.

Categories