How can I share data between components through a service? - angular11

I am having trouble sharing information between components. What I am trying to do is, show in the home.component.html data that is generated in the about.component.ts.
The operation would be:
By means of a button in the home.component.html, a function in the home.component.ts is called, this function calls a function of the about-service.ts, which collects the data from the about.component.html that obtains the about.component.ts data.
This is my home.component.html:
<button mat-menu-item (click)="goToAbout()">
<mat-icon svgIcon="logoBN"></mat-icon>
Acerca
</button>
This is my home.component.ts:
import { AboutComponent } from '../about/about.component';
export class HomeComponent {
public aboutInfo: AboutService;
goToAbout() {
.subscribe(emitData =>
}
}
From the goToAbout() function of the home.component.ts I need to get the data from the aboutBuild() function of the about.component.ts:
This is my about.component.ts:
import { AboutService } from '';
export class AboutComponent {
ngOnInit() {
}
aboutBuild() {
......code.........
}
}
This is my about.component.html:
<header class="title-color" fxFlex>Build Info</header>
I have created a function in the service to try to communicate both components.
about-service.ts:
observer = new Subject();
public subscriber$ = this.observer.asObservable();
emitData(aboutBuild) {
this.observer.next(aboutBuild);
}
But I can't access the aboutBuild() function of the about.component.ts, what do I need to include in the service to communicate the two components?

The AboutService is fine you have one public subscriber and a function to trigger event.
Your goToAbout() in home.component.ts :
export class HomeComponent {
constructor(public aboutService: AboutService) {}
goToAbout() {
let data = {key: 'value'};
this.aboutService.emitData(data);
}
}
Then your about.component.ts:
export class AboutComponent {
constructor(public aboutService: AboutService) {}
ngOnInit() {
this.aboutService.subscriber$.subscribe(data => {
this.aboutBuild(data);
});
}
aboutBuild(data) {
console.log(data)
}
}

Related

Could not Detect Online Connectivity in Angular 11

I tried to show online status in angular 11.
I did same as like this https://dzone.com/articles/how-to-detect-the-internet-connection-status-in-an
My ts.file
import { ConnectionService } from 'ng-connection-service';
isConnected = true;
noInternetConnection: boolean;
constructor(private connectionService: ConnectionService,) {
this.connectionService.monitor().subscribe(isConnected => {
this.isConnected = isConnected;
if (this.isConnected) {
this.noInternetConnection=false;
}
else {
this.noInternetConnection=true;
}
})
}
my.html file
<nb-action *ngIf="noInternetConnection">
<p>online</p>
</nb-action>
<nb-action *ngIf="!noInternetConnection">
<p>offline</p>
</nb-action>
BUT it shows offline. MY wifi connection is on
Can anyone help me to find the bug?
I personally don't recommend to use another library to listen for native browser events as this makes the application more robust, and probably the library does the same as the following code :(
When I achived such functionality I created event listeners for the native "online" and "offline" events.
Here is the network monitor service.
import { Injectable } from '#angular/core';
import { fromEvent, ReplaySubject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
#Injectable()
export class NetworkStatusService {
private init: boolean = navigator.onLine;
private online: ReplaySubject<boolean> = new ReplaySubject();
get initStatus() {
return this.init
}
constructor() {
if (this.init==false) {
this.online.next(false);
}
fromEvent(window, "online").subscribe((val) => {
this.online.next(true);
})
fromEvent(window, "offline").subscribe((val) => {
this.online.next(false);
})
}
getOnlineStatus() {
return this.online.pipe(distinctUntilChanged());
}
}

how to show id, compliantype in angular 7 with using asp.net core web api>

i am using asp.net core web api for backend and angular 7 for front end .i created database using code first
approach and then i added one more table called Complains .now i wan to return complains table id and two or three more columns from complains table using get request. then get these values in angular and show some where .
//this is interface method
Object UserComplainInformation(Complains complains);
//this is service class which implements above interface
public Object UserComplainInformation(Complains complains)
{
var resp = new
{
Id = _appDbContext.Complains.FindAsync(complains.Id),
Type =complains.Type
};
try
{
_appDbContext.Complains.FindAsync(resp);
return resp;
}
catch(Exception ex)
{
throw ex;
}
//Controller
[HttpGet]
// [Route("complainInformation")]
public Object UserComplainInformation(Complains complain)
{
return _complains.UserComplainInformation(complain);
}
//angular service code
import { Injectable } from '#angular/core';
import { ToastrService } from 'ngx-toastr';
import { ConfigService } from './util/config.service';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class ComplainHistoryService {
BaseUrl : string ='';
constructor( private config:ConfigService, private http:HttpClient) {
this.BaseUrl =config.getApiURI();
}
ngOnInit(){ }
getUserComplainHistory(){
return this.http.get(this.BaseUrl +'/complianInformation');
}
}
//.ts file usercomplainhistory
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { ComplianHistoryService } from 'src/shared/complain-history.service';
#Component({
selector: 'app-user-complians-history',
templateUrl: './user-complains-history.component.html',
styles: []
})
export class UserComplainsHistoryComponent implements OnInit {
userDetails = sessionStorage.getItem('FullName');
userComplainDetails;
constructor(private router:Router, private complainService: ComplainHistoryService) { }
ngOnInit() {
this.complainService.getUserComplainHistory().subscribe(
res =>{
this.userComplainDetails = res;
console.log(res);
},
err =>{
console.error(err);
}
)
}
}
//this is html file where i want to show id and some more fields
<ul class="list-group">
<li class="list-group-item"><strong>FullName : </strong>{{userDetails}}</li>
<li class="list-group-item"><strong>Complian Id : </strong>{{userComplianDetails}}</li>
</ul>

Angular 6 - a few components using the same randomised data that's called only once - how to avoid 'undefined'

I'm trying to use the same data in ngOnInit of several components, the problem is, the data are random every time I subscribe to it. I can only subscribe one time in the entire run of the app. That means, if I subscribe twice, it won't have any use because each component will have something else.
I want to subscribe once in a service and to create a global variable.
but when you try to use that global variable in all the components (on ngOnInit) it is always undefined.
How can I make the components wait for that same thing that can only be called once in the app?
export class UsersService {
public allUsers: Array<Object> = []
public allUsersUrl: string = 'https://glacial-escarpment-40412.herokuapp.com/users/'
constructor(private http: HttpClient) {
this.getAllUsers().subscribe(data => {
this.allUsers = data;
console.log(this.allUsers)
})
}
getAllUsers(): Observable<any> {
return this.http.get<any>(this.allUsersUrl);
}
getUser(id: number): Observable<any> {
return this.http.get<any>(this.allUsersUrl + id);
}
}
My components:
export class FirstComponent {
constructor(private usersService: UsersService){}
ngOnInit() {
console.log(this.usersService.allUsers) //undefined
}
export class SecondComponent {
constructor(private usersService: UsersService){}
ngOnInit() {
console.log(this.usersService.allUsers) //undefined
}
Please help me :)
You have a synchronism problem. This is your scenario
1- create first component
1.1 - injecting UsersService
1.2 - UsersService request for ASYNC data (execution continues)
2- FirstComponent get and print this.usersService.allUsers (not still populated because of async request)
3- this.usersService.allUsers is still undefined
You need Subject
Something like this:
UsersService
export class UsersService {
private _allUsersSource = new Subject<Array<Object>>();
private _allUsers$ = this._allUsersSource.asObservable();
public allUsersUrl: string = 'https://glacial-escarpment-40412.herokuapp.com/users/'
constructor(private http: HttpClient) {
this.getAllUsers();
}
getAllUsers(): Observable<any> {
return this.http.get<any>(this.allUsersUrl).subscribe(
data => this._allUsersSource.next(data)
);
}
get allUsers$(): Observable<Array<Object>> {
return this._allUsers$;
}
// OTHERS
}
FirstComponent
export class FirstComponent {
subscription: Subscription;
allUsers: Array<Object>;
constructor(private usersService: UsersService){}
ngOnInit() {
this.subscription = this.usersService.allUsers$.subscribe(users => {
this.allUsers = users;
console.log(this.allUsers);
});
}
Some thing for SecondComponent

Return firebase values from a service to a component angular 6

I'm creating an application with angular 6 and firebase using angularfire2, I chose to use the firestore where I have a collection called pages like in the image:
basically I created a service - "PagesService" where I have a function that returns the data of the page that I sent. I'm trying to use getPage to return the values to my component, and assign them to the form, nothing else I tried worked, only returns an "observable" that I can not work, does anyone have an idea of what I can do?
Full code, service:
import { Injectable } from '#angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable()
export class PagesService {
private pagesCollection: AngularFirestoreCollection<any>;
private page: AngularFirestoreDocument<any>;
constructor(private afs: AngularFirestore) {
this.pagesCollection = afs.collection('pages');
}
getPage(pageName: string) {
return this.afs.doc<any>('pages/${pageName}').valueChanges();
}
addPages(pageName: string, pageForm: any) {
this.pagesCollection.doc(pageName).set(pageForm.value);
}
}
My component:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup } from '#angular/forms';
import { Observable } from 'rxjs';
import { PagesService } from '../../services/pages.service';
#Component({
selector: 'app-quem-somos',
templateUrl: './quem-somos.component.html',
styleUrls: ['./quem-somos.component.scss']
})
export class QuemSomosComponent implements OnInit {
pageForm: FormGroup;
pageName: string = "wo-we-are";
page: any;
constructor(private pagesService: PagesService, private fb: FormBuilder) { }
ngOnInit() {
this.page = this.pagesService.getPage(this.pageName);
console.log(this.page);
this.pageForm = this.fb.group({
title: '',
content: ''
});
}
save() {
this.pagesService.addPages(this.pageName, this.pageForm);
}
}
obs: Sorry my english
If I have understand you right, When you say "Observable that I cannot work" is mean that you cannot access his data when you are trying to assign its values in the form?
In this case (I assume that your service is working as expected), just subscribe to it and populate the form after your values are ready to use. for example:
ngOnInit() {
this.pagesService.getPage(this.pageName).subscribe(v => {
// Here your data is ready, so you can send it to a function and populate the form as you need.
this.populateForm(v);
});
// Here I just construct the FormGroup, so your application can rendered.
this.pageForm = this.fb.group({
title: '',
content: ''
});
}
And add this function to do the task:
populateForm = (data) => {
console.log(data); // Just log it in console, and see if its the data that you seek for
}
Instead of console.log() you can populate your form or do what ever you need to.
Good Luck !
--EDIT--
I just noticed now, In your service:
getPage(pageName: string) {
return this.afs.doc<any>('pages/${pageName}').valueChanges();
}
You call the doc with ' ' instead of ``, so In fact, you are not using Template Strings. So your call is wrong and not fetch with the right path.
Change it to:
return this.afs.doc<any>(`pages/${pageName}`).valueChanges();

Connecting React Component with Redux Store

Very basic simple GET example for react-redux
I have a "MockAPI" which simulates a GET request to an API like so:
const dashboards = [
{
"Id":1,
"title":"Overview"
},
{
"Id":2,
"title":"Overview"
},
{
"Id":3,
"title":"Overview"
},
{
"Id":4,
"title":"Overview"
}
];
class DashboardApi {
static getAllDashboards() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(Object.assign([], dashboards));
}, delay);
});
}
}
I am trying to develop in a react-redux flow of dispatching an action via a button click and then updating the component via the redux store.
Here is my component code:
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import * as dashboardActions from '../../actions/dashboardActions';
class HomePage extends React.Component {
constructor(props) {
super(props);
this.loadDashboards = this.loadDashboards.bind(this);
}
loadDashboards() {
this.props.dispatch(dashboardActions.loadDashboards());
}
dashboardItem(dashboard, index) {
return <p key={index}>{dashboard.title}</p>;
}
render() {
return (
<div>
<h1>
Hello World!
<button onClick={this.loadDashboards}>load</button>
</h1>
{this.props.dashboards.map(this.dashboardItem)}
</div>
);
}
}
HomePage.propTypes = {
dashboards: PropTypes.array.isRequired,
dispatch: PropTypes.func.isRequired
};
function mapStateToProps(state) {
return {
dashboards: state.dashboards
};
}
export default connect(mapStateToProps)(HomePage);
And here is my dashboardActions.js:
import * as types from './actionTypes';
import dashboardApi from '../mockApi/mockDashboardApi';
export function loadDashboardsSuccess(dashboards) {
return { type: types.LOAD_DASHBOARDS_SUCCESS, dashboards };
}
export function loadDashboards() {
return dispatch => {
return dashboardApi
.getAllDashboards()
.then(dashboards => {
dispatch(loadDashboardsSuccess(dashboards));
});
};
}
And here is my reducer:
import initialState from './initialState';
import * as types from '../actions/actionTypes';
export default function dashboardReducer(state = initialState.dashboards, action) {
switch(action.types) {
case types.LOAD_DASHBOARDS_SUCCESS:
return action.dashboards;
default:
return state;
}
}
I am trying to get the onClick to load in the dashboards array and to render as <p> tags simply displaying the title value. Unfortunately it is not happening.
I see that the LOAD_DASHBOARDS_SUCCESS action is getting loaded, but I see that the dashboards property in the store is still an empty array instead of showing the returned data...
What am I missing here?
You've got a typo in your reducer. switch(action.types) should be switch(action.type) with no 's'

Resources