Exploring the capabilities of Web MIDI in the context of Angular

I am a beginner with Typescript and I am currently working on using Angular2 to develop a Web Midi application. However, I am facing some difficulties in understanding certain errors that I encounter. I believe that I should be placing the Midi functions within a Service, but please correct me if I am mistaken.

The code snippet below works perfectly fine when the midi variable and the onMIDIMessage function are placed outside:

var midi:any;

function onMIDIMessage(event) {
        console.log("msg received", event);
}

export class MidiService {

    onMidiInit() {
        if (navigator.requestMIDIAccess) {
            navigator.requestMIDIAccess({
                sysex: false
            }).then(this.onMIDISuccess, this.onMIDIFailure);
        } else {
            alert("No MIDI support in your browser.");
        }
    }

    onMIDISuccess(midiAccess) {
        console.log('MIDI Access Object', midiAccess);
        midi = midiAccess;
        console.log(midi);

        var inputs = midi.inputs.values();
        for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
            input.value.onmidimessage = onMIDIMessage;
        }

    }

    onMIDIFailure(e) {
        console.log(e);
    }
}

Everything is functional and I can successfully print incoming MIDI messages with this setup. However, what baffles me is that when I move the onMIDIMessage function and the midi variable inside the MidiService class, Chrome throws an error. Can anyone explain why this occurs?

midi.service.ts:24 Uncaught (in promise) TypeError: Cannot read property >'onMIDIMessage' of undefined at MidiService.onMIDISuccess (http://localhost:3000/app/midi.service.js:27:57)

var midi:any;

// Code snippet that causes issues
export class MidiService {

    onMidiInit() {
        if (navigator.requestMIDIAccess) {
            navigator.requestMIDIAccess({
                sysex: false
            }).then(this.onMIDISuccess, this.onMIDIFailure);
        } else {
            alert("No MIDI support in your browser.");
        }
    }

    onMIDISuccess(midiAccess) {
        console.log('MIDI Access Object', midiAccess);
        midi = midiAccess;
        console.log(midi);

        var inputs = midi.inputs.values();
        for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
            input.value.onmidimessage = this.onMIDIMessage;
        }

    }

    onMIDIMessage(event) {
        console.log("msg received", event);
    }

    onMIDIFailure(e) {
        console.log(e);
    }
}

---EDIT

The methods are called in the app.component.ts file.

import {Component} from 'angular2/core';
import {MidiService} from './midi.service';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>',
    providers: [MidiService]
})
export class AppComponent { 
    constructor(midiService: MidiService) {
        midiService.onMidiInit();
    }
}

Answer №1

It seems that this is not referring to the instance of the class.

To ensure proper context, include .bind(this) when assigning current class methods as callbacks:

button.onclick = this.onClick.bind(this);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guidelines for implementing more rigorous type checks in TypeScript:

I am looking to enhance the code validation process and eliminate any implicit 'any' types. To achieve this, I have set "strict": true in my tsconfig.json. { "compilerOptions": { "target": "ES5", ...

Exploring the capabilities of Angular 8 Services using 'TestHttpInterceptor'!

My Angular front-end is relatively small, but it relies heavily on data from an external server. I'm encountering issues with my tests throwing a gyp error. While I can mock the service to test a simple component, this approach only allows me to rep ...

Ways to set up react-script without overwriting tsconfig.json during 'start' execution

I am currently utilizing create-react-app to kickstart a project of mine. My goal is to configure paths in tsconfig.json by incorporating these changes to the default tsconfig.json file created by create-react-app: "baseUrl": "./src", "paths": { "interf ...

Integration of NextAuth with Typescript in nextjs is a powerful tool for authentication

I am diving into NextAuth for the first time, especially with all the new changes in Nextjs 13. Setting up nextauth on my project seems to be a daunting task. I have gone through the documentation here I am struggling to configure it for nextjs 13. How do ...

Revitalize 404 - Setting up URL rewrites for an Angular application on Ubuntu hosted on Azure

I recently deployed my Angular 14 app to an Azure App Service and I'm facing some issues with setting up rewrite rules to prevent 404 errors when refreshing routes. The main page (index.html) loads fine, but navigating directly to a route within the a ...

Issue with remote URL mismatch when attempting to upload to Git using angular-gh-pages

I have just completed transitioning my project to use an angular workspace and now I am looking to deploy my demo application using angular-gh-pages. The repository link is https://github.com/Gillardo/ngx-bootstrap-datetime-popup In my package.json, I hav ...

Simulating TypeDI service behavior in Jest

My current setup includes Node with TypeScript, TypeDI and Jest. I've been working on creating services that have dependencies on each other. For example: @Service() export class MainService{ constructor(private secondService: SecondService){} public ...

Guide to locating the recursive function in Node.js runtime

As a beginner in the world of node and angular development, I have encountered a major issue - "FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory". Is there anyone who can help me identify the function ...

Angular component with @Input() directive allows data to be passed into

I am curious about how the @Input property's rendering works internally. In Angular, if I create a component with type and title as @Input properties, how does the component know that the value of the type property should be treated as a string, whil ...

Every time my Canvas loads, it consistently fills up the entire width but neglects to occupy the complete height

My Canvas is only taking full width, but not full height. Here's my code snippet in an attempt to make it both full width and full height: export class AimComponent implements OnInit { @ViewChild('canvas') myCanvas: ElementRef; public ...

Contrasting type[] (array) with [type] (tuple)

If we imagine having two interfaces: interface WithStringArray1 { property: [string] } interface WithStringArray2 { property: string[] } Let's define variables of these types: let type1:WithStringArray1 = { property: [] } let type2:Wit ...

Having trouble entering text into a React input field

Encountering a puzzling issue with a simple form featuring an input field that inexplicably won't respond to keyboard typing. Initially, suspicions pointed towards potential conflicts with the onChange or value props causing the input to be read-only. ...

Error: Unable to access null properties while attempting to address Readonly property error by implementing an interface

Here is the code snippet I am working with: interface State { backgroundColor: boolean; isLoading: boolean; errorOccured: boolean; acknowledgment: string; } export class GoodIntention extends React.Component<Props, State> { ... onCli ...

Passing multiple parameters in a service call from Angular to Django

I have successfully implemented a file uploader with a date picker on Django, where the data is uploaded to a database using sqlalchemy in a standalone Python class. Now, I am facing a challenge while trying to migrate the UI aspect to an Angular Front End ...

Is it possible to integrate an Angular-CLI 8 library into an Angular 2, 4, 5, 6, or 7 application without any problems? Would it be compatible

I have been developing and distributing an Angular library via NPM using custom scripts during the Angular 5 era. Fortunately, this library is free from any challenging peer dependencies and works seamlessly with Angular 5 through 8 applications. Now, I a ...

Sending JSON Data from Angular2 Component to Node.js Server

Currently, I am facing an issue where I am unable to successfully insert data into a database using Angular2 and Node.js. Upon running my script, I use console.log(this.address); to verify that I am passing json, and the output in the console is as follow ...

What is the proper way to implement an if-else statement within objects?

Is there a way to convert the code below into an object structure so I can access nodID and xID keys from different files? The issue lies in the if statement within the code. My idea is to use export const testConfig = {} and import testConfig into any fil ...

What is the technique for obtaining a complete AST representation of a union type in TypeScript?

Although I am familiar with ts-ast-viewer, I am unsure of how they extract a list of elements from the union. I have experimented with different existing solutions, such as this one, but it appears that most of them are outdated. Some ts.[methods] have be ...

Display the values from form fields in Angular2 after dynamically adding them

I am struggling to output the values of each object in the choices array using console log. Despite being able to display the objects in the choices array, all the values appear empty. Every object is showing as timeZonePicker: "", startTimeInput: "", endT ...

Tips for testing two conditions in Angular ngIf

I am facing a little issue trying to make this *ngIf statement work as expected. My goal is to display the div only if it is empty and the user viewing it is the owner. If the user is a guest and the div is empty, then it should not be shown. Here is my cu ...