OnEvent within another onEvent allowed?


#1

I have a student that wants to provide the option of two different type of games in the Clicker App - if the user clicks catButton, then the game behaves one way, and if dogButton, another way. She attempted this with two different functions: a catFunction in the catButton event handler, and a dogFunction in the dogButton event handler. Each function contains a series of onEvents.

The problem is that even though it appears that her code assigns the variables for lives and score back to the game’s defaults after a lost game, if you play the game again, the numbers go up and down by two points (instead of one). It’s as if the user is trapped in a double function.

We understand that she could probably fix this problem by creating two screens with a separate series of onEvents, but she wanted to try to handle it with functions on one screen. And now we’re really curious as to why the logic behaves this way. Is this problem due to having onEvents embedded within an onEvent? (I also realize there might be something entirely different amiss in the logic; I’m new at this myself.)

Link to her app: https://studio.code.org/projects/applab/8LzBx-P-pzWMaDI61Kl6M28c_y4uBnNVr2BTQ3fw-GM/edit

Thank you!


#2

Oooh, this is a tricky misconception about how event handlers work. When you call onEvent() it creates a new event handler sitting in the background responding to events. Once you’ve created an event handler, there’s no way to get rid of it. When you restart the game the old event handlers are still hanging out in the background and new event handlers are created, which is why you see it changing by 2 instead of one.

As a rule, you should never put an onEvent() block inside another block in order to prevent duplicating your event handlers. One approach to getting the kind of behavior your student is looking for would be to create a single event handler at the top level for each of “dogclicker” and “catclicker” and then use a variable to track whether you have chosen dog or cat mode. This could roughly look like this:

var target = "dogclicker";

onEvent("dogclicker", "click", function() {
  if (target == "dogclicker") {
    score = score + 1;
  } else {
    lives = lives - 1;
  }
}

onEvent("catclicker", "click", function() {
  if (target == "catclicker") {
    score = score + 1;
  } else {
    lives = lives - 1;
  }
}

#3

Thanks so much for the explanation and example code!

This forum has been great to reference, and the students have responded so well to the curriculum - it’s our first year for it.


#4

Could this be considered an abstraction? In the survival guide any examples with onEvent do not earn a point.


#5

@agrant great question, and nice observation. That is correct, event handlers are not “student-generated” abstractions. According the AP rubric:

The following are examples of abstractions (EK 5.3.1):
o Procedures
o Parameters
o Lists
o Application program interfaces (APIs)
o Libraries

For the purposes of AppLab, functions (which are really just procedures) are probably the easiest and most straight forward way to get the “abstraction” points.


#6

Hi Kaitie, (I was in your PD this past summer in Philly)
So is the best advice to students working in App Lab on the Create Task to not use OnEvent AT ALL or just not to claim it as a student created abstraction or algorithm (leaving the OnEvent OUTSIDE the rectangle and circle)?

If a student were to try to create the same function on their own without OnEvent (say "if a button is clicked, trigger an event) is that even possible to do in App Lab?


#7

Hi @jbailey,

onEvent is the built in mechanic for “registering” event listeners with the system. There is no other way to do it. However, you could take the code that you wrote inside an event handler function and break it out into a named function that you call from the event handler. A trivial example (don’t get distracted by what the code is trying to do initially):

Instead of this:

onEvent("btn1","click",function(){
    var base = 2;
    var exp = 8;
    var result = base;
    for(var i=0; i<exp-1; i++){
       result = result * base;
    }
   console.log(result);
} 

DO THIS:

onEvent("btn1","click", function(){
    twoToTheEighth();
} 

function twoToTheEighth(){
  var base = 2;
  var exp = 8;
  var result = base;
  for(var i=0; i<exp-1; i++){
       result = result * base;
  }
  console.log(result);
}

Now it would be overall better if (a) you had reason to call that function from some other place in the code as well (b) it’s parameterized (i.e. function myExp(base, exp)) and © it actually does something non-trivial for some actual purpose :slight_smile:

Hope that helps.

Baker


#8

I have a student who has created an app with several screens and wants the score to update at the end or throughout the game. He has created several variables but none seem to keep track of the score at the end. Is it possible to keep track of a score with a multi screen app?


#9

Yes. Score needs to be a global variable. Also, make sure the text box is getting updated each time the score changes. Ask the student to look at the Clicker Game developed earlier.

Please note, the CSP Principles Course and Exam Description states on page 83 that once the Create PT has begun teachers may not “write, revise, amend, or correct student work, including debugging the program, writing or designing functionality of the program, testing the program, or making revisions to the program”. If this question is about an ongoing Create PT, then rather than helping the student debug this issue, I highly recommend that you advise your student to only use App Lab features or programming constructs over which they already have mastery.


#10

This is a question on whether or not it can be done in app lab. I understand about not intervening but I also don’t want them to attempt to do something that isn’t possible on this platform. In most of the examples I have seen in this platform the score is always just updated on one screen, not several. What they are creating has several screens with questions on each screen. They want the score to be updated on every screen and at the end keep track of the score and display a total at the end. They have created several variables to calculate the scores and labels but none seem to work. Is what they are doing something that is feasible within app lab?


#11

Yes it is possible. The student must make sure that “score” is a global variable and all UI Elements that are showing the value of score (textbox or label) are updated each time score changes. Here is a link to my code for clicker game. I have commented out some parts of the code to make it easier to play and see the score getting updated.


#12

Thank you. From what I saw the student had something similar. I will just advise them to go back and debug since I am can’t tell them what is exactly wrong with the program. But them knowing it is possible will allow them to forge forward. Thanks again.