Tips for asynchronously updating a model in TypeScript

I have been working on a function to hide the element for connecting to Facebook upon successful connection. I have implemented two functions, success and error, which trigger after Firebase successfully logs in the user. While I can confirm that these functions are working correctly through debugging and console.log statements, the element does not hide when the Facebook connection is successful. Upon inspecting the properties of this, I noticed that isFacebookConnected and isGoogleConnected do not appear, but the User and Providers properties do.

I am wondering if there might be something I am misunderstanding about passing the current model reference to a function in order to modify the UI state. How can I ensure that the UI element hides on successful connection?

FacebookAuthenticator.ts

import { firebase } from '../../app';
import { IAuthenticator } from './IAuthenticator';
import { Navigator } from '../navigation/Navigator';

export class FacebookAuthenticator implements IAuthenticator  {
    public successFunction: Function;
    public errorFunction: Function;

    constructor(success: Function, error: Function) {
        this.successFunction = success;
        this.errorFunction = error;
    }

    public authenticate() {
        const successFunction = this.successFunction;
        const errorFunction = this.errorFunction;

        firebase.login({
            type: firebase.LoginType.FACEBOOK
        }).then(
            function (result) {
                successFunction(result);
            },
            function (errorMessage) {
                errorFunction(errorMessage);
            }
        );
    }
}

AccountViewModel.ts

export class AccountViewModel extends Observable {
    public appVersion : string;
    public User : User;
    public isFacebookConnected : boolean;
    public isGoogleConnected : boolean;
    private authenticator : IAuthenticator;
    private providers : Array<Provider>;

    constructor() {
        super();

        appVersion.getVersionName().then((result) => {
            this.notifyPropertyChange("appVersion", "Version " + result);
        });

        firebase.getCurrentUser().then((result) => {
            this.User = result;
            this.notifyPropertyChange("User", this.User);
            this.providers = ProviderParser.getUserProviders(this.User);
            this.setProviderConnectivty();
        });
    }

    public setFacebookSwitch(togglingOn : boolean) {
        const successFunction : Function = (model : AccountViewModel) => {
            return () => {
                model.isFacebookConnected = true;
                model.notifyPropertyChange("isFacebookConnected", model.isFacebookConnected);
            }
        };

        const errorFunction : Function = (model : AccountViewModel) => {
            return () => {
                model.isFacebookConnected = false;
                model.notifyPropertyChange("isFacebookConnected", model.isFacebookConnected);
                dialogs.alert({
                    title: "Unexpected Error",
                    message: "An unexpected error occurred during login. Please contact the developer.",
                    okButtonText: "Ok"
                });
            }
        };

        this.authenticator = new FacebookAuthenticator(successFunction(this), errorFunction(this));

        if (togglingOn && this.providers.indexOf(Provider.Facebook) === -1) {
            this.authenticator.authenticate();
        }
    }
}

Account.xml

<StackLayout row="2" column="0" class="preferenceGroup">
            <Label text="Connected Accounts" class="preferenceGroupHeading"/>
            <GridLayout rows="*" columns="*, auto" visibility="{{ isFacebookConnected ? 'collapsed' : 'visible' }}">
                <Label row="0" column="0" text="Facebook" class="preferenceItem"/>
                <Label row="0" column="0" 
                        text="Repeat accesses your public profile, friend list, and email address" 
                        textWrap="true"
                        horizontalAlignment="left"
                        class="preferenceSubText"/>
                <Switch loaded="facebookSwitchLoaded" />
            </GridLayout>
            <Label class="divider" />
            <GridLayout rows="*" columns="*, auto">
                <Label row="0" column="0" text="Google" class="preferenceItem"/>
                <Label row="0" column="0" 
                        text="Repeat accesses your public profile, friend list, and email address" 
                        textWrap="true"
                        horizontalAlignment="left"
                        class="preferenceSubText"/>
                <Switch checked="{{isGoogleConnected}}"/>
            </GridLayout>
        </StackLayout>

Answer №1

Seems like the variable model is not pointing to the correct model you are currently working with. The appropriate object should be referenced as this within the closure.

Try making changes to your code in the following manner to see if it resolves the issue:

public setFacebookSwitch(togglingOn : boolean) {
        const successFunction : Function = (model : AccountViewModel) => {
            return () => {
                this.isFacebookConnected = true;

If the above modification does not solve the problem (especially if the Function is overriding the context of this), attempt saving a reference to this in a temporary variable first:

public setFacebookSwitch(togglingOn : boolean) {
        const myTempThis = this;
        const successFunction : Function = (model : AccountViewModel) => {
            return () => {
                myTempThis.isFacebookConnected = true;

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

Universal customization for Material-UI Select

I am attempting to customize the appearance of a select component within a React project using MUI 5. Specifically, I want to modify the border size and color when the select component is in focus. While other components can be styled globally using styleO ...

Triggering an event within a component to execute a specific function in another component

I am working on a component that includes multiple routes such as home, app, and navbar. My goal is to have the encrementcalc() function execute when the navbar button is pressed. I attempted to use the event emitter but was unsuccessful. Can someone prov ...

Leveraging information beyond the socket.on function

I'm trying to work with socket data in a way that allows me to compare it outside of the initial socket.on function. I've attempted using global variables without success. One thought I had was grouping the data, but one is an io.emit and the oth ...

Can you explain the significance of "@c.us" in the context of whatsapp-web.js?

Are there any references or resources available for using "@c.us" that I can consult? Here is an example: client.on('ready', () => { console.log('Client is ready!'); // Your message. const text = "Hey John"; // Obt ...

Outdated compiler module in the latest version of Angular (v13)

After upgrading to Angular 13, I'm starting to notice deprecations in the usual compiler tools used for instantiating an NgModule. Below is my go-to code snippet for loading a module: container: ViewContainerRef const mod = this.compiler.compi ...

The HTML required attribute seems to be ineffective when using AJAX for form submission

Having trouble with HTML required attribute when using AJAX submission I have set the input field in a model Form to require attribute, but it doesn't seem to work with ajax. <div class="modal fade hide" id="ajax-book-model" a ...

Console is displaying a Next.js error related to the file path _next/data/QPTTgJmZl2jVsyHQ_IfQH/blog/post/21/.json

I keep getting an error in the console on my Next.js website. GET https://example.com/_next/data/QPTTgJmZl2jVsyHQ_IfQH/blog/post/21/.json net::ERR_ABORTED 404 I'm puzzled as to why this is happening. Could it be that I'm mishandling the router? ...

Testing the React context value with React testing library- accessing the context value before the render() function is executed

In my code, there is a ModalProvider that contains an internal state managed by useState to control the visibility of the modal. I'm facing a dilemma as I prefer not to pass a value directly into the provider. While the functionality works as expecte ...

Creating a connection to an external website through a JavaScript function within an Angular application

I am currently working on an Angular application. Within the index.html file, there is a header that contains links to external websites. <a href="#" onclick="getExternalUrl('about.html');">Click here </a> <scr ...

In Production environment, v-model triggers a ReferenceError

My Vue View includes the following code: <script setup> import Overwrite from "../components/Overwrite.vue"; </script> <template> <div> ... <textarea v-model="text" cols="99" rows=&qu ...

Unexpected unhandled_exception_processor in Google Chrome

I keep encountering a strange uncaught exception handler in Google Chrome. After updating all follow buttons to download JavaScript asynchronously, I noticed an error in the content.js file mentioned in the exception message which advises against polluting ...

Perform an HTTP GET request to a RESTful service with specified parameters using Angular 2

I'm currently facing an issue while attempting to create a GET request to the YouTube Web API. I'm struggling with passing parameters through the http.get function and have confirmed the request is being sent using Fiddler. However, I keep receiv ...

Exploring the Angular TypeScript Method for Rendering Nested Objects in an Array

Within this array, I have a collection of objects that contain properties for model and color. My goal is to present these objects in a table format, with individual access to the color values. grp = [ {model: "CF650-3C", color: {Orange: 3, Black ...

Apache causes HTML download tag to malfunction

I have an HTML file that includes the following code: <a href="/Library/WebServer/Documents/file.zip" download="file.zip"> Download here </a> When I test this HTML page on Chrome, it successfully allows me to download the file. However, when ...

Having trouble adjusting the label fontSize in ReactJS when using semantic-ui-react?

Is there a way to decrease the size of the label for a form input? In this scenario, attempting to set the fontSize does not work: <Form.Input label="Username" style={{fontSize: '10px'}} /> Does anyone have any suggestions on how to res ...

The HTML canvas drawImage method overlays images when the source is modified

Trying to implement a scroll animation on my website, I came across a guide for creating an "Apple-like animation" using image sequences. Even though I'm new to Angular, I attempted to adapt the code to work with Angular. However, instead of animatin ...

Utilize ng-repeat to display a series of images, with the first image being placed within a unique div

My challenge lies in displaying product images using ng-repeat, where one image is located in a separate div. Let me share my code and explain what is happening. The API response provides product details and images [{"id_product":"1000","name":"Nikolaus ...

Steps for loading a different local JavaScript file by clicking on a button

My goal is to reload the browser page and display a different ReactJS component/file when a button is pressed. Initially, I attempted using href="./code.js" or window.location="./code.js" within the button props, but unfortunately, it did not yield the des ...

Different from Local system, the code refuses to work when deployed on the server

I have implemented a basic form where onSubmit it collects the values and passes them to a JavaScript page (via an AJAX call), then sends the data to add.php and returns the result back to the HTML page. The code functions correctly on my local system, but ...

Transform the character encoding from a non-standard format to UTF-8

Imagine a scenario where there is a page with <meta charset="EUC-KR">, let's call it address-search.foo.com, that allows users to search for an address and sends the data to a specified URL by submitting an HTML form using the POST met ...