5

I am making a small application with Angular7 on Front and Flask on Back, what i am tryig to do is to subscribe for a service then to save the returned data into an object type variable from inside my main AppComponent, then to access this varialbe in all my other components.

Api service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) { }

  CheckApi(){
    return this.http.get('http://localhost:5000/')
  }

}

AppComponent

import { Component, OnInit, Injectable } from '@angular/core';
import { ApiService } from './api.service'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  title = 'Inbox App';

  public text: object

  constructor(private data: ApiService){}

  ngOnInit(){
    this.data.CheckApi().subscribe(data => {
        this.text = data
        console.log(this.text)
    })
  }
}

And here is where i am trying to access that object from within another component:

LoginComponent

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

login.component.html

<section>
    <legend class="text-center">{{ text }}</legend>
</section>
6
  • 1
    here is a working example stackblitz.com/edit/angular-hq3uam Commented Mar 16, 2019 at 21:54
  • @JasonWhite, thanks for your interest, but why this.apiService.data; returns Observable object not data from server? Commented Mar 16, 2019 at 22:14
  • I didn't have a service to use, you could put an http call in the CheckApi method and get data. I commented out the api call to have a working example for you to see. Commented Mar 16, 2019 at 22:22
  • I updated the stackblitz with the api call. Not test so you might have to modify a bit. Commented Mar 16, 2019 at 22:25
  • I think i got it solved, just needed to subscribe to it first :) Commented Mar 16, 2019 at 22:37

4 Answers 4

3

I have created service for this purpose in my project which saves all data I want in objects property. And then it's possible to access it from everywhere in the project.

import {Injectable} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataStorage {
  private dataStorage = {};

  addData(key: string, data: any) {
    this.dataStorage[key] = data;
  }

  getData(key: string) {
    return this.dataStorage[key];
  }

  clearData(key: string) {
    this.dataStorage[key] = undefined;
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

What is the thing with changed object?
Probably a typo from when I cleaned my code for this snippet. Thank you! It's removed.
2

This can be done several way. Best is to use angular input

import { Component, OnInit, Input } from '@angular/core';

@Component({
 selector: 'app-login',
 templateUrl: './login.component.html',
 styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
@Input() text: string; 
constructor() { }

ngOnInit() {
}

}

Then you can pass variable from parent component to child component like this

<app-login text="yourvariable or object"></app-login>

Comments

0

Using a public property on the App component that can be accessed from other components is not a conventional Angular way of sharing state between components, so I would advice against it.

I would either have used an @Input on the child components so that you can pass the object down to the child component, more info here: https://angular.io/guide/component-interaction

Or I would have used a Service with a BehaviorSubject as described here https://medium.com/@weswhite/angular-behaviorsubject-service-60485ef064fc

Comments

0

This is probably the most common and straightforward method of sharing data. It works by using the @Input() decorator to allow data to be passed via the template, when there is parent child relationship. Also you can look into @ViewChild Decorator. Also look into EventEmitter.

When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should you a shared service. When you have data that should aways been in sync, I find the RxJS BehaviorSubject very useful in this situation. Refer below link:

https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.