Issue - firestore has not been defined (Occurs strictly after the use of "then")

Having an issue: I successfully create fake users in my database, but encounter a problem when starting the 'for' loop.

The error I'm facing is:

Error adding document: TypeError: Cannot read property 'firestore' of undefined

I've attempted various solutions without success. Any suggestions?

Appreciate any help!

create_NewUser(data:any){
        this.firestore.collection('Users-test').add({
          name:data.name,
          town:data.town,
          gender:data.gender,
          email:data.email,
          picture:data.picture,
          birthdate:data.birthdate
        })
        .then(function(docRef) {
          let nbInterest:any = data.interests.length;
          for (let index = 0; index < nbInterest; index++) {
            this.firestore.collection('Users-test').doc("/" + docRef.id + "/interests/" + index).add({
              interest:data.interests[index]
            }) 
          }
        })
        .catch(function(error) {
            console.error("Error adding document: ", error);
        });
      }

Answer №1

Referenced from this source:

In traditional function expressions, the behavior of the this keyword varies depending on the context in which it is invoked. On the other hand, arrow functions bind this lexically, meaning that they use the value of this from the surrounding code block.

Therefore, when passing a function as an argument to then, this will not be defined.

Using Arrow Functions

An arrow function can be used to retain the context of the "surrounding" this.

.then((docRef) => {
    // handle 'this' here
})

Explicitly Binding this

You have the option to explicitly bind an object to a function so that it behaves as this within the function itself.

.then(function(docRef) {
     // handle 'this' here
}.bind(this))

Answer №2

Follow these steps:

Within your create_NewUser function:

const that = this;

When inside a for loop, utilize the following:

that.firestore
.collection('Users-test').doc("/" + docRef.id + "/interests/" + index).add({
......
});

This is necessary because 'this' is not accessible within the scope of the 'then' function.

Implementation:

create_NewUser(data:any){
        const that = this;
        this.firestore.collection('Users-test').add({
          name:data.name,
          town:data.town,
          gender:data.gender,
          email:data.email,
          picture:data.picture,
          birthdate:data.birthdate
        })
        .then(function(docRef) {
          // console.log("Document written with ID: ", docRef.id);
          let nbInterest:any = data.interests.length;
          // let nbAvailaibilities:any = data.interests.length;
          for (let index = 0; index < nbInterest; index++) {
            that.firestore.collection('Users-test').doc("/" + docRef.id + "/interests/" + index).add({
              interest:data.interests[index]
            }) 
          }
        })
        .catch(function(error) {
            console.error("Error adding document: ", error);
        });
      }

Using binding as suggested by scorpioo590 can also be helpful.

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

Watching - transforming / combining

I am a beginner when it comes to working with Observables. Here's the Effect that I am using: My goal is to dispatch the PositionUpdateAction or PositionFailedAction before the SunriseSunsetAction is dispatched. Currently, what happens is that the r ...

Why did the developers of Angular 2+ choose to use JavaScript Objects instead of Typescript Classes for defining Router routes?

When working with the Angular 2+ Router, the standard approach involves defining routes in the app-routing module. app-routing.module.ts import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; ...

Utilizing custom types in React with TypeScript and Prop-Types

Currently, I am working with a string type literal that looks like this: type MyType = 'str1' | 'str2' | 'str3'. I need one of my props to only accept this specific type, but I'm struggling to specify this in PropTypes. ...

The type 'number' cannot be assigned to the type 'Element'

Currently, I am developing a custom hook called useArray in React with TypeScript. This hook handles array methods such as push, update, remove, etc. It works perfectly fine in JavaScript, but encounters errors in TypeScript. Below is the snippet of code f ...

Angular 9: Chart.js: Monochromatic doughnut chart with various shades of a single color

My goal is to display a monochromatic doughnut chart, with each segment shaded in varying tones of the same color. I have all the necessary graph data and just need to implement the color shading. ...

Discovering a specific property of an object within an array using Typescript

My task involves retrieving an employer's ID based on their name from a list of employers. The function below is used to fetch the list of employers from another API. getEmployers(): void { this.employersService.getEmployers().subscribe((employer ...

Using interfaces for typecasting in TypeScript

Consider the code snippet below: let x = { name: 'John', age: 30 } interface Employee { name:string, } let y:Employee = <Employee>x; console.log(y); //y still have the age property, why What is the reason for TypeScript ov ...

TS2339 Error: The object 'Navigator' does not contain the property 'clipboard'

In the project I'm working on, there is an error that comes up when trying to copy custom data to the clipboard. It's something I can easily put together. Error TS2339: Property 'clipboard' does not exist on type 'Navigator' ...

Generate a collection of elements using a different collection as a reference

I am struggling with an array of objects: let data = [{ createdDate: "2222", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="087c6d7b7c3d487c6d7b7c266b6765">[email protected]</a>", histories: [ ...

Steps to prevent subfolder imports in my npm package

My npm package is built using: typescript webpack webpack.config: {... entry: './src/index.ts } library tree: - package.json - src - - index.ts - - ...all_my_code... I have all my library functionality and types exported from the index.ts file. T ...

Display and conceal table columns dynamically in Vue by utilizing the Vuetify data table functionality

Looking for an example: How to show hide columns of vuetify data table using v-select list I have created something similar, but I'm facing an issue where the table doesn't refresh when changing the header data: https://codepen.io/Meff1/pen/vY ...

Creating a ref in React with TypeScript to access the state of a child component

Is there a way to access the state of a child component within the parent component without using handlers in the child or lifting the state up in the parent? How can I utilize refs in React with TypeScript to createRef and retrieve the child's state ...

Exploring Recursive Types in TypeScript

I'm looking to define a type that can hold either a string or an object containing a string or another object... To achieve this, I came up with the following type definition: type TranslationObject = { [key: string]: string | TranslationObject }; H ...

Enhancing TypeScript with Generic Proxyify Functionality

I'm attempting to enclose a basic interface provided through a type generic in order to alter the return value of each function within the interface. For instance: interface IBaseInterface { test(a?: boolean, b?: number): Promise<boolean>; ...

Navigational bar mishaps: troubleshooting the "is not a function error" in layout.tsx

I recently started learning React (Next.js) and I'm working on adding a navbar feature to my project. The goal is to have the active navlink stand out when the user is on the corresponding page. To achieve this, I created a function that updates the s ...

Endlessly streaming data is requested through HTTP GET requests

I am facing an issue with my code where it requests data endlessly. The service I have retrieves data in the form of an Array of Objects. My intention is to handle all the HTTP requests, mapping, and subscriptions within the service itself. This is because ...

Typescript does not allow for extending an interface with a data property even if both interfaces have the same data type

I've encountered a peculiar problem with Typescript (using Visual Studio 2012 and TypeScript v0.9.5) that I could use some help clarifying. The code snippet below functions correctly: interface IA { data: any; } interface IB { data: any; } ...

How to Utilize Class Members in a Callback Function in Angular 12 with Capacitor Version 3

When I click the "Device Hardware Back Button" using Capacitor 3.0, I'm trying to navigate to the parent component with the code below. The device back button is working correctly, but I'm facing an issue where I can't access class members i ...

Is it necessary for Vue single file components (.vue files) to use `export default` or is it possible to use named exports instead?

export default may no longer be the recommended way to export modules, as discussed in these resources: After changing my Vue components from this: <script lang="ts"> 'use strict'; import {store} from '../../data/store' ...

A step-by-step guide on enhancing error message handling for Reactive forms in Angular

Here is a code snippet that I'm working on: public errorMessages; ngOnInit(): void { this.startErrorMessage(); } private startErrorMessage() { this.errorMessages = maxLength: this.translate.instant(' ...