New to svelte and javascript, web app for learning solfege - javascript

I am new to JavaScript and Svelte. For a school project, I want to create a web application to learn the basics of solfeggio, but I have found a way to do it, but I feel that it's not the right way at all
Right now I have an array that represents my sheet music staff, of another array of int that represents my lines, and i update like this code snippet:
onMount(()
const interval = setInterval(() => {
rand();
portee[wch_line].main[pos] = 1;
portee[wch_line].main[pos + 1] = 0;
if (pos === 0) {
reset();
}
pos -= 1;
}, 10);
return () => {
clearInterval(interval);
};
});```
I shift my 1 on my array from 0, and then I display the note at the location of the 1, otherwise I display a "-" which visually represents my line. Here is the link to my git if you want to take a look: https://github.com/BaptisteKELAGOPIAN/SolfegeLearning. But as I said, it's slow at times, but most of all I don't want to continue like this when I feel there is a better way to do all of this. If you have any leads, it would be great, thank you.

Related

How to rotate from different titles

No, I am not talking about <h1> or something like that. I am talking about the <title> element. I created a function, that delays every .5 seconds or so, and changes titles.
The script I have developed reads the array, which includes the titles, and rotates from it. The first time I have ran it, I did not use setTimeout, and it ran instantly, I couldnt read anything.
But when I tried using the setTimeout function, it started to return undefined. What is the problem with this code?
for(var i = 0; i < titles.length ; i++){
setTimeout(function () {document.title = titles[i]}, 500)
}
You're going about this the wrong way (IMO). Using a loop you'll fire off all your timeouts at once. You'd be better off using setInterval
let i = 0, titles = ['title1', 'title2', 'title3'];
let int = setInterval(() => {
document.title = titles[i];
console.log('doc.title: ', document.title);
if (i++ >= titles.length - 1) clearInterval(int);
}, 500)

Why is my array appearing empty after appearing to have an element in it?

I'm trying to make a discord bot that randomly shuffles an array of planets and then picks one to hide a bounty on. Then, if a player has that planet role, they can search for the bounty, The problem is whenever I search for the bounty on the planet, it says that the array is empty, but when I shuffle the planets and show the result, the array doesn't appear to be empty.
This is the shuffling code.
let coreworlds = [verzan, albregao, corellia, rishi, coruscant, vurdon, wobani]
let coreworldsresult = []
case 'start':
function shuffle(coreworlds) {
for (let i = coreworlds.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[coreworlds[i], coreworlds[j]] = [coreworlds[j], coreworlds[i]];
}
}for (let i = 0; i < 1000000; i++) {
shuffle(coreworlds);}
coreworldsresult.push(coreworlds[1]);
message.channel.send('A small bounty has been set somewhere in the core worlds. You will have 6 hours to find the bounty.');
message.channel.send(coreworldsresult);// This always shows the random world.
setTimeout(() => {
if(coreworldsresult.lenght != 0){
coreworldsresult.length = 0
message.channel.send('Nobody claimed the bounty in time. It`ll take me another 12 hours before I can find another small bounty.')
}else{
coreworldsresult.length = 0
message.channel.send('I`m gonna be getting another small bounty in 12 hours.')
}
}, 21600000);
setInterval(() => {
function shuffle(coreworlds) {
for (let i = coreworlds.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[coreworlds[i], coreworlds[j]] = [coreworlds[j], coreworlds[i]];
}
}for (let i = 0; i < 1000000; i++) {
shuffle(coreworlds);}
coreworldsresult.push(coreworlds[1])
message.channel.send('A small bounty has been set somewhere in the core worlds. You will have 6 hours to find the bounty.')
setTimeout(() => {
if(coreworldsresult.lenght != 0){
coreworldsresult.length = 0
message.channel.send('Nobody claimed the bounty in time. It`ll take me another 12 hours before I can find another small bounty.')
}else{
coreworldsresult.length = 0
message.channel.send('I`m gonna be getting another small bounty in 12 hours.')
}
}, 21600000);
}, 64800000);
This is the searching code.
case 'search':
message.channel.send('You look around for the bounty.')
message.channel.send(coreworldsresult.length);// This always comes back as "0"
if(member.roles.cache.some(r => r.name === coreworldsresult || midrimresult || outerrimresult)){
message.reply('you found a bounty! Now shoot him with `!attack <large, medium, or small>-
bounty <weapon>`!')
}else{
message.reply('you did not find anything. Try a different planet.')
}
break;
I figured out that the reason was because my arrays were declared under the
client.on('message', message =>{
so the changes to them only applied to the code in the same case area. I fixed this by putting the arrays at the top.
Being a new to programming, one thing I would suggest when getting stuck with unexpected outcomes is to work from the top down and create cases where you KNOW what the outcome should be and eventually you'll get down to the part of your code that has either a syntax error or a logical error.
I usually add console logs to all my conditionals when debugging problems.
Like #EvanMorrison said you have typo in the word length
setTimeout(() => {
if(coreworldsresult.lenght != 0){
also please use the DRY principal (Dont't repeat yourself), by wrapping your code in functions and then use them as many time as you need

Creating a for loop that loops over and over =

So I have a weird problem (as I can do this using dummy code, but cannot make it work in my actual code) -
The concept is simple - I need a for loop that upon hitting its max "I" number reverts "I" to 0 again and creates a loop over and over -
DUMMY CODE:
for(i=0;i<10;i++){
console.log(i);
if(i === 10){
i = 0
}
}
Now for the longer code (sorry)
function reviewF(){
// add ID to each of the objects
reviews.forEach((e, i)=>{
e.id = i
})
// get the elements to be populated on page
var name = document.querySelector('p.name');
var date = document.querySelector('p.date');
var rating = document.querySelector('.rating_stars');
var review = document.querySelector('p.review_content_text');
// reverse the array - so the newest reviews are shown first (this is due to how the reviews where downloaded)
var reviewBack = reviews.slice(0).reverse();
// start the loop - go over each array - take its details and apply it to the elements
/**
* THIS IS WHAT I WOULD LIKE TO LOOP OVER FOREVER
*
* **/
for (let i = 0; i < reviewBack.length; i++) {
(function(index) {
setTimeout(function() {
// document.getElementById('reviews').classList.remove('slideOut')
name.classList.remove('slideOut')
date.classList.remove('slideOut')
rating.classList.remove('slideOut')
review.classList.remove('slideOut')
name.classList.add('slideIn')
date.classList.add('slideIn')
rating.classList.add('slideIn')
review.classList.add('slideIn')
name.innerHTML = reviewBack[i].aditional_info_name;
date.innerHTML = reviewBack[i].Date;
rating.innerHTML = '';
review.innerHTML = reviewBack[i].aditional_info_short_testimonial;
if(reviewBack[i].aditional_info_short_testimonial === 'none'){
reviewBack.innerHTML='';
}
var numberOfStars = reviewBack[i].aditional_info_rating;
for(i=0;i<numberOfStars;i++){
var star = document.createElement('p');
star.className="stars";
rating.appendChild(star);
}
setTimeout(function(){
// document.getElementById('reviews').classList.add('slideOut')
name.classList.add('slideOut')
date.classList.add('slideOut')
rating.classList.add('slideOut')
review.classList.add('slideOut')
},9600)
}, i * 10000)
})(i);
// should create a infinite loop
}
console.log('Loop A')
}
// both functions are running as they should but the time out function for the delay of the transition is not?
reviewF();
EDITS >>>>>>>>
Ok so I have found a hack and slash way to fix the issue - but its not dry code and not good code but it works.....
this might make the desiered effect easier to understand
reviewF(); // <<< this is the init function
// this init2 function for the reviews waits until the reviews have run then
// calls it again
setTimeout(function(){
reviewF();
}, reviews.length*1000)
// this version of the innit doubles the number of reviews and calls it after that amount of time
setTimeout(function(){
reviewF();
}, (reviews.length*2)*1000)
From trying a bunch of different methods to solve this issue something I noticed was when I placed a console.log('Finished') at the end of the function and called it twice in a row (trying to stack the functions running..... yes I know a horrid and blunt way to try and solve the issue but I had gotten to that point) - it called by console.log's while the function was still running (i.e. the set time out section had not finished) - could this have something to do with it.
My apologies for the rough code.
Any help here would be really great as my own attempts to solve this have fallen short and I believe I might have missed something in how the code runs?
Warm regards,
W
Why not simply nest this for loop inside a do/while?
var looping = True
do {
for(i=0;i<10;i++){
console.log(i);
}
if (someEndCondition) {
looping = False;
}
}
while (looping);
I would think that resetting your loop would be as simple as setting "i = 0" like in the dummy code. So try putting the following into your code at the end of the for loop:
if(i === 10){
i = 0;
}

recursive function with multiple parameters in javascript/reactjs

I am writing some react code, in which I build a list of diagnoses. These diagnoses are build dynamically, so one can add sub diagnoses and attributes to them by clicking them. Therefore, I want to know where some potential diagnosis is placed in my list, and therefore when creating a new diagnosis, I give it a path as an attribute, which I can then use to navigate to it from the list.
I want to be able to set an attribute 'showRequirements' to a given diagnosis, and for this I implement the following two functions:
onClick = (path) => () => {
let currentDiagnosis = this.state[path[0].type][parseInt(path[0].key, 10)];
if (path.length > 1) {
this.showRequirementsFromPath(path, currentDiagnosis.algorithm.children, 1)
}
else {
currentDiagnosis.showRequirements = !currentDiagnosis.showRequirements;
}
this.setState({
[this.state[path[0].type][parseInt(path[0].key, 10)]]: currentDiagnosis,
})
}
showRequirementsFromPath = (path, diagnosis, counter) => {
if (counter < path.length) {
diagnosis[path[counter].key].showRequirements = true;
this.showRequirementsFromPath(path, diagnosis[path[counter].key], counter + 1);
}
else {
diagnosis.showRequirements = !diagnosis.showRequirements;
}
}
The onClick works when the path has length 1, so I believe the problem is in the showRequirementsFromPath function. If I run this with a path of length > 1, the app crashes, and I get the error message 'Too much recursion'. However, if I delete the diagnosis.showRequirements = !diagnosis.showRequirements from the else in showRequirementsFromPath, the app doesn't crash, and it does everything perfectly besides setting the attribute showRequirements.
This is my first post in here, so please tell if I'm breaking some guidelines/what I can do better in future posts.
Thanks in advance!
Edit: As asked, the type of path[0].key is String. Note that path[counter].key is an integer when counter > 0.
Update: I am so sorry, I just found out that the problem was elsewhere in the code. I believe the code I have posted is actually correct.

How to cycle through an array of Audio objects

I've recently started learning Javascript, and I'm working on my first web-embedded game, which is a musical puzzle game that uses the basic principals of twelve-tone serialist music. My game is mostly done, and you can find it here. But I'm having trouble with audio. I did manage to get it to play a sound when the user solves the puzzle, but I can't get it to actually play through the notes that appear on the game board.
Here's what I did: I created an array of 12 Audio objects, which contains every note from C to B. Then I created a method called "playToneRow()" which plays through them all, with the order determined by the numeric array ToneRow.notes[]. Here's the code:
this.playToneRow = function()
{
for (var i in this.notes)
{
noteSound[this.notes[i]].play();
}
};
But this method only plays the last note of the tone row. Now I should mention that my knowledge of Javascript has been cobbled together from various tutorials I've found online, and I'm fairly certain that there are significant gaps in my admittedly rudimentary coding skills. But I figured that the problem was that I wasn't putting any space in between the sounds, so it was trying to play them all at once, but it didn't have enough channels so it only played the last one. So then I tried this:
this.playToneRow = function()
{
var x = 0;
for (var i in this.notes)
{
x = this.notes[i];
setTimeout(function()
{
noteSound[x].play();
}, 700);
}
};
Now I'm really not sure if I'm using setTimeout() properly, but I'm guessing not, because once again, it only played the last note. I know that all 12 wav files are getting loaded, because if I change the tone row, it will play a different note. So it does have access to all the audio files; it's just a matter of getting it to play them all (and in the right order).
Thanks!
for won't really care about your setTimeout, try:
this.playToneRow = function()
{
var x = 0,
length = 0,
j = 0;
for (var i in this.notes)
{
length += 1;
}
function runIteration () {
x = this.notes[j];
setTimeout(function()
{
noteSound[x].play();
}, 700);
if (j === length) return;
j += 1;
setTimeout(runIteration, 700);
}
runIteration();
};
Hopefully that does it. I've taken a look at your code but its a bit complex so I wasn't able to determine if this.notes was an object or an array
http://jsfiddle.net/kgvgcsg3/14/
var notes = [{'0':'tone1'},{'1':'tone2'}]
var playToneRow = function(i)
{
setTimeout(function()
{
//notes[i].play(); goes here
console.log(notes[i])
if (i < notes.length-1){
i++;
playToneRow(i)
}
}, 700);
};
playToneRow(0)

Categories