data being released from variables in angular ionic

I am truly perplexed as to why the variables aren't holding their values.
I've declared a variable user and initialized it with data from the userData() function. However, it appears as undefined when I log it within the constructor as well as in the ProfilePage.

https://i.sstatic.net/L1w17.png

share-service.ts

export class ShareService {
  uid: string;
  user;

  constructor(public db: AngularFireDatabase) {
    let currentUser = firebase.auth().currentUser;
    this.uid = currentUser.uid;
    this.userData();
    console.log('[constructor]user: ', this.user);
  }

  userData() {
    this.db.object(`users/${this.uid}`).snapshotChanges().subscribe(data => {
      this.user = data.payload.val();
      console.log('[userData]user: ', this.user);
    });
  }

  getUser() {
    return this.user;
  }

}

profile.ts

export class ProfilePage {
  user;

  constructor(public navCtrl: NavController, public firebaseService: FirebaseService, shareService: ShareService) {
    console.log('[profile.ts]', shareService.getUser());
  }

}
  • "angularfire2": "5.0.0-rc.4",
  • "firebase": "4.8.2",
  • "ionic-angular": "3.9.2",
  • "rxjs": "^5.5.6",
  • "@ionic/app-scripts": "3.1.8",
  • "typescript": "2.4.2"

I have attempted to find solutions by researching similar issues such as this one. It seems that the problem lies in Angular's asynchronous nature, leading me to explore concepts like promises as suggested in posts like this. There was also mention of using .then().

Despite my efforts to implement these suggestions in my specific case, I encountered various syntax errors.

Your guidance would be greatly appreciated.

Answer №1

Angular offers the Async Pipe specifically designed for handling asynchronous methods.

User information is retrieved from the Firebase server, and this process takes some time. Meanwhile, JavaScript continues its execution.

This explains why you may receive this.user as undefined, as the data has not arrived from the server at that point of execution.

In order to manage such scenarios, there are different approaches available:

  • Callback -- Convert callbacks to promises (callback to promises)
  • Promises -- Learn about promises
  • Async-Await -- Explore how async-await works
  • Observables -- Especially in Angular applications, consider using observables

Here's an example implementation:

share-service.ts

export class ShareService {
 uid: string;

 constructor(public db: AngularFireDatabase) {
 let currentUser = firebase.auth().currentUser;
 this.uid = currentUser.uid;
 }

 getUser() {
   return this.db.object(`users/${this.uid}`)
     .snapshotChanges()
     .map(data => data.payload.val());
 }
}

profile.ts

export class ProfilePage {
 user;

 constructor(public navCtrl: NavController, public firebaseService: 
  FirebaseService, shareService: ShareService) {
  this.user = shareService.getUser();
 }
}

Template Usage

<div *ngIf="user | async as _user; else loadingUsers">
  {{_user.username}}
</div>
<ng-template #loadingUsers>
  Loading...
</ng-template>

Answer №2

Below is the breakdown of how to interpret the code snippet:

 userData() {
    return this.db.object(`users/${this.uid}`).snapshotChanges()
    .pipe(map(data => {

      this.user = data.payload.val();
      return this.user;
      console.log('[userData]user: ', this.user);
    }));//import { map } from 'rxjs/operators/map';

}

To access it anywhere, utilize subscribe() on getUser().

  getUser(){
    if(!this.user){
        return this.userData();//return the db call if not set
    }else{
    return of(this.user);//import {of} from 'rxjs/Observable/of;'
  }

In the constructor method,

  constructor(public db: AngularFireDatabase) {
    let currentUser = firebase.auth().currentUser;
    this.uid = currentUser.uid;
    this.getUser().subscribe(u=>{
        console.log('[constructor]user: ', u);
    });//subscribe to the observable.
  }

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

Having difficulties creating a new instance of a class

I'm encountering an issue with this TypeScript code import Conf = require('conf'); const config = new Conf(); The Problem: the expression is not constructable and the imported module lacks construct signatures It's puzzling because th ...

eliminating the hues beneath the lines on Morris region charts

I'm seeking advice on how to remove colors below the lines in Morris area charts. Any ideas? Here's the code snippet I've been using: Morris.Area({ element: 'area-example', data: [ { y: '2006', a: 100, b: 90 }, ...

Transforming timestamps to month day, year format and back again without the use of any NPM packages

I have developed a microservice that converts Unix timestamps to a format like Dec 01, 2017 and vice versa. The microservice is deployed at this link: timestamp I am wondering if there is a better way to achieve this without using third-party NPM modules. ...

contrasts in regex special characters: .net versus javascript

Here is my current javascript implementation: EscapeForRegex = function(input) { var specials = ["[", "\\", "^", "$", ".", "|", "?", "*", "+", "(", ")", "{", "}"] for (var k in specials) { var special = specials[k]; ...

javascript the debate between inline and traditional registration

Hey there, I'm a JavaScript beginner and currently learning about inline vs. traditional registration. I've managed to get code block 1 (inline) working perfectly fine, but unfortunately, code block 2 (traditional) isn't cooperating. Can som ...

Generating PDF files from HTML using Angular 6

I am trying to export a PDF from an HTML in Angular 6 using the jspdf library. However, I am facing limitations when it comes to styling such as color and background color. Is there any other free library besides jspdf that I can use to achieve this? Feel ...

Using .NET for client-side WCF communication with queuing functionality

Updating Legacy Software Library Currently, I am in the process of modernizing an old software library that relies on a perpetually looping System.Threading.Thread to execute queued processes. These processes involve making requests to another outdated sy ...

Angularfire allows for easy and efficient updating of fields

Currently, I am working on creating a basic lateness tracker using AngularFire. So far, I have successfully added staff members to the miniApp and set the initial late minutes to a value of 0. My challenge lies in updating these values. Ideally, when a us ...

Acquire an array of Worksheet names in JavaScript by utilizing ActiveX

How can I retrieve a comprehensive list of all available sheet names from my Excel file using the ActiveX Object? I am aware that the code Excel.ActiveWorkBook.Sheets provides access to the sheets. However, how do I obtain an array containing the NAMES of ...

When the child state changes the parent state, useEffect may not be triggered for the first time

Component for children export const FlightRange = (props) => { const [value, setValue] = useState(props.value); return ( <> <input type='range' min={1000} max={50000} step="500&quo ...

Why is it that I am limited to running globally installed packages only?

Recently, I made the switch to Mac iOS and encountered an issue while setting up a new TypeScript backend project. All npm packages seem to be not functioning properly in my scripts. Cannot find module 'typescript/bin/tsc' Require stack: - /Users ...

Testing Angular 11 methods using Jest unit tests within a .then block

Currently, I am running jest unit tests in Angular 11 and facing an issue while testing methods within the .then method. It seems like the test methods are not being executed at the expect method. I need guidance on how to structure the test code to ens ...

tips for loading json data into jqgrid

Utilizing the struts2-jquery-jqgrid plugins, I have created a Grid with a filter-search feature. The Grid includes a drop-down list in the column assigned_user for filtering based on the selected option from the drop-down list. <s:url var="remoteurl" a ...

What are the issues with using AJAX in conjunction with a for-loop?

I'm currently developing a small application that needs to create work schedules and calculate hours: . I've written the function kalkulacja() to calculate the inputs for each row and output the results through ajax. However, I'm facing an i ...

Combining Elasticsearch with AngularJS or Node.js

I am currently developing a MEAN stack application that utilizes elasticsearch for searching records. In my AngularJS controller, I have implemented the following code to interact with the elasticsearch server: instantResult: function(term) { var client = ...

Ways to verify if element has been loaded through AJAX request

I am trying to determine if an element has already been loaded. HTML <button>load</button> JS $(document).on('click','button',function () { $.ajax({ url: 'additional.html', context: document ...

Tips for creating a binding between an HTTP service and a variable in AngularJS that adjusts when the server data is modified

Using an http get request in angular to extract data into an object with the users currently connected to my app requires refreshing the information every time for binding to the scope. To achieve this, I implemented a method to refresh the data from the a ...

Struggling to implement JSS hover functionality in a project using React, Typescript, and Material UI

I am a newcomer to the world of React/Typescript/Material UI and I am trying to understand how to work with these technologies together. While researching, I came across a similar question related to using hover with Material-UI. However, the syntax was d ...

Activate lighting in Three.js with a simple click

I successfully loaded a sphere mesh with Lambert material. Now, I am trying to add a light source to the point where there is an intersection after clicking. target = object that was clicked. to = vector3 of my click. When the dblclick event listener is ...

Discovering which chip has wrapped to the next line in Material UI Autocomplete can be found by closely inspect

Currently, I am working with a Material UI autocomplete feature that functions as follows: https://i.sstatic.net/4LrwI.png My goal is to determine when the fourth chip wraps to the next line within the autocomplete so that I can proceed with additional c ...