Hello so my problem is that I am trying to make a shared-service because I need an array in an other component. It seems like the "sender" class is working also as the service class itself. Just the "reciever" class isn't getting any data through the description. What do I need to change here to get it working?
Service:
import { Injectable } from "#angular/core";
import { Observable, Subject } from 'rxjs';
import { Note } from '../note/note-data';
#Injectable()
export class DataService {
exchangeData$: Observable<Note[]>
private dataSubject = new Subject<Note[]>()
constructor() {
this.exchangeData$ = this.dataSubject.asObservable()
}
exchangeData(data) {
console.log(data)
this.dataSubject.next(data)
}
}
Sender Class:
import { Component, OnInit } from '#angular/core';
import { NoteComponent } from 'src/app/note/note-component';
import { Note } from 'src/app/note/note-data';
import { Content } from '#angular/compiler/src/render3/r3_ast';
import { ContentSearcher } from './searcher/ContentSearcher';
import { DataService } from './ChangeDataService/DataService';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'noteApp';
public notes: Note[] = [
new Note("example title 1", "blablablalblalalblablabla", new Date(5000), new Date(5000)),
new Note("example title 2", "example description 2", new Date(5000), new Date(5000)),
new Note("example title 3", "example description 3 noch mehr blablalblalbla", new Date(5000), new Date(5000))
]
public constructor(private dataService:DataService) {
this.dataService.exchangeData(this.notes)
}
deleteNote(note: Note) {
var index = this.notes.indexOf(note, 0);
this.notes.splice(index, 1);
}
Reciever class:
import { Component, OnDestroy } from "#angular/core";
import { ContentSearcher } from './ContentSearcher';
import { Note } from '../note/note-data';
import { DataService } from '../ChangeDataService/DataService';
import { Subscription } from 'rxjs';
#Component({
selector: 'content-searcher',
templateUrl: './content.searcher.html',
styleUrls: ['./content.searcher.css']
})
export class ContentSearcherComponent implements OnDestroy {
public notes: Note[] = []
private subscription:Subscription
public constructor(private dataService: DataService) {
console.log("notes (constructor before init): "+this.notes)
this.subscription = this.dataService.exchangeData$.subscribe((data) => {
this.notes = data
console.log("notes in content.searcher (CONSTRUCTOR): "+this.notes)
})
console.log("subscription: "+this.subscription)
}
searcher: ContentSearcher = new ContentSearcher()
matchingNotes: Note[]
onKey(event) {
console.log("notes in content.searcher: "+this.notes)
const inputValue = event.target.value
if (this.notes != null) {
this.matchingNotes = this.searcher.searchContent(inputValue, this.notes)
}
}
getMatchingNotes(): Note[] {
return this.matchingNotes
}
ngOnDestroy() {
this.subscription.unsubscribe()
}
}
Related
This seems to be resolved if I remove HttpClient from PCService and comment out this line:
return this.http.get<PC>(this.pcUrl + "find/" + id);
main-content.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Observable } from 'rxjs';
import { PC } from '../../models/pc';
import { PCService } from '../../services/pc.service';
#Component({
selector: 'app-main-content',
templateUrl: './main-content.component.html',
styleUrls: ['./main-content.component.scss']
})
export class MainContentComponent implements OnInit {
pc!: Observable<PC>;
constructor(private route: ActivatedRoute,
private service: PCService) { }
ngOnInit(): void {
this.route.params.subscribe(params =>
{ const id = params['id'];
this.pc = this.service.getPCById(id);
}
);
}
}
pc.service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { PC } from '../models/pc';
#Injectable({
providedIn: 'root'
})
export class PCService {
constructor(private http: HttpClient) {
}
readonly pcUrl = 'http://localhost:8080/api/v1/pc/';
getPCById(id: number) {
return this.http.get<PC>(this.pcUrl + "find/" + id);
}
}
I am trying to push a message into an array that is already declared as a variable in the component. I am using a service and have created a subject observable to take data from one component and inject it into another component. When I try to push the data onto the array after subscribing to the variable, it's updated temporarily but when I open that component, the data is not pushed. The array updates when I console log from inside the subscribe method but it's reset once I open that component. I don't know what is the problem. This is the code:
Service.ts
import { Injectable } from '#angular/core';
import { User } from './user';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class SerService {
private message = new Subject<string>();
sourceMessage$ = this.message.asObservable();
constructor() { }
sendMessage(message: string) {
this.message.next(message);
}
}
Receiver component
import { Component, OnInit } from '#angular/core';
import { SerService } from '../ser.service';
import { User } from "../user";
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
public messages = ['hi', 'hello', 'bye'];
constructor(private _service: Service) { }
ngOnInit() {
this._service.message$
.subscribe(
message => {
this.messages.push(message);
}
);
}
}
Sender Component
import { Component, OnInit } from '#angular/core';
import { SerService } from '../ser.service';
import { User } from '../user';
#Component({
selector: 'app-sign-up',
templateUrl: './sign-up.component.html',
styleUrls: ['./sign-up.component.css']
})
export class SignUpComponent {
userModel = new User('', '', '', '', false);
constructor (private _service : SerService) {}
onSubmit(){
this._service.sendMessage(this.userModel.message);
}
}
I can't update the message array. How do I do this with minimal changes?
You can create a service to send data from one component to another by using BehaviourSubject
Service:
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable({
providedIn: 'root'
})
export class DataService {
private userDetails = new BehaviorSubject<any>('');
currentUserDetails = this.userDetails.asObservable();
constructor() { }
sendUserDetails(message){
this.userDetails.next(message)
}
}
Sender Component:
import { DataService } from '/services/data.service';
export class SignupComponent implements OnInit {
public userDetails;
constructor(private _dataService: DataService) {}
ngOnInit(){
userDetails = new User('', '', '', '', false);
this._dataService.sendUserDetails(this.userDetails);
}
}
Receiver Component
import { DataService } from '/services/data.service';
export class LoginComponent implements OnInit {
public userDetails;
constructor(private _dataService: DataService) {}
ngOnInit(): void {
this._dataService.currentUserDetails.subscribe(userDetails => this.userDetails = userDetails);
}
Blockquote
I'm a newbie and learning Angular.
I want to pass data between two components (not a parent-child component). I write a service.ts file to achieve it then met this error. I have found a lot in Stackoverflow, but seems no effects.
I don't know what went wrong, so I will put all the code out.
Below is the code.
By the way, how to solve "It looks like your post is mostly code; please add some more details."?
//service
import { Injectable } from '#angular/core';
import {Observable} from 'rxjs';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class TransfermessageService {
public receiveMsg:any;
constructor() { }
public subject = new Subject<any>();
sendMessage(message: any) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
//component 1
import { Component, OnInit } from '#angular/core';
import {RequestService} from '../../../services/request/request.service';
import {Router,NavigationStart, GuardsCheckEnd,ResolveStart,NavigationError, Event as NavigationEvent } from '#angular/router';
import {TransfermessageService} from '../../../services/common/transfermessage/transfermessage.service';
#Component({
selector: 'app-login-session-code',
templateUrl: './login-session-code.component.html',
styleUrls: ['./login-session-code.component.scss'],
})
export class LoginSessionCodeComponent implements OnInit {
public riskRole: string = localStorage.getItem('userRole');
public sessioncode: any;
public token_user: any;
constructor(
public RS: RequestService,
public router: Router,
public TMS: TransfermessageService,
) {
}
ngOnInit(){
}
checkInputCall(){
const api = this.RS.baseURL+ '/login/checkInput';
const token_api= this.RS.baseURL+ '/login/checkToken';
const parameters:object = {
"email": localStorage.getItem('email'),
"input": this.sessioncode,
"type": localStorage.getItem('type')
}
this.RS.checkInput(api,parameters).subscribe(res => {
if(res['data'].input_check) {
localStorage.setItem('checkInput', JSON.stringify(res['data']));
this.RS.checkToken(token_api,{"token": res['data'].user.token}).subscribe(res => {
this.token_user = res;
this.TMS.sendMessage({"ss": "ssss"});
this.router.navigate(['/home']);
// console.log(res); //return token_user
})
}else {
alert("session code is not true");
}
})
}
ngAfterViewChecked(): void {
this.router.events.subscribe((event: NavigationEvent) => {
if(event instanceof NavigationStart) {
console.log(event);
}
});
this.router.events.subscribe((event: NavigationEvent) => {
if(event instanceof GuardsCheckEnd) {
console.log(event,'GuardsCheckEnd');
}
});
this.router.events.subscribe((event: NavigationEvent) => {
if(event instanceof NavigationError) {
console.log(event,'NavigationError');
}
});
}
}
//components 2
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import {TransfermessageService} from '../../services/common/transfermessage/transfermessage.service';
import {Subscription} from 'rxjs';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
providers: [TransfermessageService]
})
export class HomeComponent implements OnInit {
public ctrlHomeDetailTag: boolean = true;
public ctrlHomeBasicTag: boolean = true;
public ctrlTags: boolean = true;
public receiveMsg: any;
constructor(
public router: Router,
public TMS: TransfermessageService,
public Subscription: Subscription
) {
}
ngOnInit(): void {
console.log('home page');
const receiveMsg = this.TMS.getMessage();
console.log(receiveMsg,'parameters');
}
// ngAfterViewInit():void {
// this.Subscription = this.TMS.getMessage().subscribe(message => {
// this.receiveMsg = JSON.parse(message);
// console.log('this.receiveMsg', this.receiveMsg);
// })
//}
ngonChanges() {
}
ngDoCheck() {
}
ngOnDestroy(): void {
// this.Subscription.unsubscribe();
}
}
I have API for getting information about one specific restaurant in the database, but I have to get it with a POST request. I successfully get restaurantID from auth.service and another API when the restaurant is logged in, But when I tried to log restaurant in console, I get undefined. Uniformly I don't have permission to show API here. The code:
restaurant.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Restaurant } from '../models/Restaurant';
import { LoggedRestaurant } from '../models/LoggedRestaurant';
import { AuthService } from './auth.service'
#Injectable({
providedIn: 'root'
})
export class RestaurantService {
private restaurantUrl = 'https://dm.dnevnimeni.com/dmnew/podacirestorana.php';
public restaurant: Restaurant;
public loggedRestaurant: LoggedRestaurant
public restaurantID = this.authService.currRestaurant[0].id
constructor(private http: HttpClient, private authService: AuthService) { }
getRestaurant(ID): Observable<LoggedRestaurant> {
console.log('ID je' + this.restaurantID);
return this.http.post<LoggedRestaurant>(this.restaurantUrl, ID);
}
}
informacije.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../services/auth.service';
import { RestaurantService } from '../services/restaurant.service';
import { Restaurant } from '../models/Restaurant';
import { LoggedRestaurant } from '../models/LoggedRestaurant';
import { Observable } from 'rxjs';
#Component({
selector: 'app-informacije',
templateUrl: './informacije.component.html',
styleUrls: ['./informacije.component.scss']
})
export class InformacijeComponent implements OnInit {
restaurant: Restaurant;
loggedRestaurant: LoggedRestaurant;
restaurantID = this.authService.currRestaurant[0].id;;
constructor(private restaurantService: RestaurantService, private authService: AuthService ) { }
getRestaurant() {
this.restaurantService.getRestaurant().subscribe(data => {
this.loggedRestaurant = data;
});
}
ngOnInit() {
this.getRestaurant();
this.restaurant = this.authService.currRestaurant[0];
console.log(this.restaurant)
console.log(this.loggedRestaurant)
this.restaurantID = this.restaurant.id;
console.log(this.restaurantID)
this.restaurantService.restaurantID =this.restaurantID;
}
}
Update
Your code should be like this
Since you just need to get data you dont have to use post
so you can change from this
return this.http.post<LoggedRestaurant>(this.restaurantUrl, this.restaurantID);
to this
return this.http.get<LoggedRestaurant>(`${this.restaurantUrl}/${this.restaurantID}`);
and add in ngOnInit
ngOnInit() {
this.restaurantService.getRestaurant().subscribe(data => {
this.loggedRestaurant = data;
// do something else
});
Because your getRestaurant() method is not called in ngOnInit life cycle hook so the data is not avaibled
You have a few issues with your code. First, you never actually call the getRestaurant() function, thus the service call will never be requested.
Second, you're dealing with asynchronous code and can't expect the service call to be complete before the console.log(this.loggedRestaurant) is run.
My suggestion is that you change your function to return an Observable<LoggedRestaurant> and subscribe to that.
getRestaurant(): Observable<LoggedRestaurant> {
this.restaurantService.getRestaurant().subscribe(data => {
this.loggedRestaurant = data;
});
}
Then you can use it as
ngOnInit() {
this.getRestaurant().subscribe(loggedRestaurant => {
console.log(loggedRestaurant);
});
}
Try this:
informacije.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../services/auth.service';
import { RestaurantService } from '../services/restaurant.service';
import { Restaurant } from '../models/Restaurant';
import { LoggedRestaurant } from '../models/LoggedRestaurant';
import { Observable } from 'rxjs';
#Component({
selector: 'app-informacije',
templateUrl: './informacije.component.html',
styleUrls: ['./informacije.component.scss']
})
export class InformacijeComponent implements OnInit {
restaurant: Restaurant;
loggedRestaurant: LoggedRestaurant;
restaurantID;
constructor(private restaurantService: RestaurantService, private authService: AuthService ) { }
getRestaurant() {
this.restaurantService.getRestaurant().subscribe(data => {
this.loggedRestaurant = data;
});
}
ngOnInit() {
this.getRestaurant(); // add this line
this.restaurant = this.authService.currRestaurant[0];
console.log(this.restaurant)
console.log(this.loggedRestaurant)
this.restaurantID = this.restaurant.id;
console.log(this.restaurantID)
this.restaurantService.restaurantID =this.restaurantID;
}
}
I am trying to practice behaviorsubject in angular 5. I am written a small app with two components and want to change the value in both of them at once but the value is not changing. BehaviorSubject should change the value in all the components. Please help me understand.
Service
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class TestserviceService {
public isAdmin = new BehaviorSubject<boolean>(false);
cast = this.isAdmin.asObservable();
constructor() { }
changeAdmin(){
this.isAdmin.next(!this.isAdmin);
}
}
Component One
import { Component, OnInit } from '#angular/core';
import{ TestserviceService } from '../../testservice.service';
#Component({
selector: 'app-one',
templateUrl: './one.component.html',
styleUrls: ['./one.component.css']
})
export class OneComponent implements OnInit {
isAdmin: boolean;
constructor(private testservice: TestserviceService) { }
ngOnInit() {
this.testservice.cast.subscribe(data => this.isAdmin = data);
}
changeValue(){
this.testservice.changeAdmin();
console.log(this.isAdmin);
}
}
Component One html
<button (click)="changeValue()">Click Me</button>
<p>
one {{isAdmin}}
</p>
Component Two
import { Component, OnInit } from '#angular/core';
import { TestserviceService } from '../../testservice.service';
#Component({
selector: 'app-two',
templateUrl: './two.component.html',
styleUrls: ['./two.component.css']
})
export class TwoComponent implements OnInit {
isAdmin: boolean;
constructor(private testservice: TestserviceService) { }
ngOnInit() {
this.testservice.cast.subscribe(data => this.isAdmin = data);
console.log("two "+this.isAdmin);
}
}
changeAdmin(){
this.isAdmin.next(!this.isAdmin);
}
Should be
changeAdmin(){
this.isAdmin.next(!this.isAdmin.value);
}
this.isAdmin is a BehaviorSubject and you were trying to set !thisAdmin which evaluates to false
Stackblitz
Change your service to :
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class SharedServiceService {
constructor() { }
public isAdmin = new BehaviorSubject<boolean>(false);
cast = this.isAdmin.asObservable();
changeAdmin(){
this.isAdmin.next(!this.isAdmin.value);
}
}
It should be this.isAdmin.value because this.admin will only be behaviourSubject's object
Live Demo