Why can't I fetch a file in angular 2? - javascript

Basically I am trying to fetch a csv file to parse it later using d3.
I have created a special component to fetch the data, and pass it to another component to parse it.
The fetch-data component is as follows:
import {Component, Injectable} from '#angular/core';
import {Http, Response, Headers, RequestOptions, HttpModule} from "#angular/http";
import {Observable} from 'rxjs/Rx';
#Component({
selector: 'app-fetch-data',
templateUrl: './fetch-data.component.html',
styleUrls: ['./fetch-data.component.css'],
providers: [HttpModule]
})
#Injectable()
export class FetchDataComponent {
constructor(private http: Http) {
}
getCsv(): Observable<any> {
return this.http.get('app/districts_data/data.csv').map((res: Response) => res);
}
}
Here is the other component where the d3 code should go:
import {Component, OnInit, ElementRef} from '#angular/core';
import * as D3 from 'd3';
import {FetchDataComponent} from '../fetch-data/fetch-data.component';
#Component({
selector: 'app-dubai-dual-line-chart',
templateUrl: './dubai-dual-line-chart.component.html',
styleUrls: ['./dubai-dual-line-chart.component.css'],
providers: [FetchDataComponent]
})
export class parseData implements OnInit {
public csv;
constructor(private __fetchDataComponent: FetchDataComponent) {}
ngOnInit() {
this.getCsv();
}
private getCsv() {
this.__fetchDataComponent.getCsv().subscribe(
data => {
this.csv = data
},
err => console.error(err),
() => console.log('done loading csv')
)
}
}
But nothing seems to be fetched. Where did I go wrong?

Related

check boolean value again and again

I am trying to build infinite scroll for my cards.
I am using a variable reload in data.service to check for need to load more data which is getting set to true when page end is getting reached.
The variable setting to true is done by app.component
The content population is done in post.component
And ```reload`` is present in data.service which is using http service to fetch for content from php server.
Curently I am using observable and trying to access reload status repeatedly but it is getting subscribed only once on Init.
app.component.ts
import { Component,HostListener } from '#angular/core';
import * as M from 'materialize-css';
import {DataService} from './current/posts/post-card/data.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent
{
title = 'cosmos';
constructor(private scrollSet: DataService){}
#HostListener('scroll', ['$event'])
onScroll(event:any)
{
if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight-100)
{
console.log("noww");
this.scrollSet.setValue(true);
}
}
}
post.component.ts
import { Component, OnInit} from '#angular/core';
import {DataService} from './data.service';
import { DomSanitizer } from '#angular/platform-browser';
import {Title} from "#angular/platform-browser";
#Component({
selector: 'app-post-card',
templateUrl: './post-card.component.html',
styleUrls: ['./post-card.component.css']
})
export class PostCardComponent implements OnInit {
constructor(private data: DataService,public sanitizer: DomSanitizer,private titleService:Title)
{
this.titleService.setTitle("Current Feed | Cosmos");
}
received = 'none';
posts: any = [];
ngOnInit()
{
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
this.data.getValue().subscribe((value) => {
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
});
}
}
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import {BehaviorSubject, Observable} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataService {
private reload: BehaviorSubject<boolean>;
constructor(private http: HttpClient)
{
this.reload = new BehaviorSubject<boolean>(false);
}
fetchGap=5; // use this to set number of results wanted per fetch
fetchEnd:number= 0;
setValue(newValue): void {
this.reload.next(newValue);
}
getValue(): Observable<boolean> {
return this.reload.asObservable();
}
getPostData(){
this.fetchEnd+=this.fetchGap;
return this.http.get('http://localhost:1234/Server/getPosts.php?fetchEnd='+this.fetchEnd+'&fetchGap='+this.fetchGap);
}
}
the problem is that you haven't set the value of reload to false after your treatment.
try to check inside post.component.ts. here is a portion of that code, the block which suscribe to reload.
post.component.ts reload block
this.data.getValue().subscribe((value) => {
if(value){
this.data.getPostData().subscribe(data =>
{
this.posts.push(data);
this.received='success';
},
error =>
{
this.received='error';
});
this.data.setValue(false);
}
});

ANGULAR. Send array data get it of Itunes API; from component-search to component-main, via service

In angular 7. I need to send an Array information get it from Itunes Api, which is included in a component called "search", to another component called "catalog". I've understand that in this case I've to use a service which allows to share the info between them. Here's some code. What's wrong?
I've tried with viewchild, input, output, but there's no result; because both components aren't "relatives".
"search"
"search"
import { Component, OnInit, Output, EventEmitter } from '#angular/core';
import { RequestService } from '../../services/request/request.service';
import {DataShareService} from '../../services/dataShare/data-share.service';
import { Music } from '../../models/music';
#Component({
selector: 'search',
styleUrls: ['./ion-searchbar.component.sass'],
templateUrl: './ion-searchbar.component.html',
providers: [RequestService, DataShareService],
})
export class IonSearchBarComponent implements OnInit {
public searchResults: Music[];
public searchValue: string;
constructor(public _requestService: RequestService, private _dataShareService: DataShareService) {}
ngOnInit() {
this._dataShareService.$sendDataObservable.subscribe(
data => {
this.searchResults = data
})
}
sendData(searchResults: Music[]){
console.log("executat");
this._dataShareService.sendData(searchResults);
}
search(){
this._requestService.getMusic(this.searchValue).subscribe(
result => {
this.searchResults = result.results;
console.log(result.results);
this.sendData(this.searchResults);
},
error =>{
console.log(<any>error);
}
);
}
}
"service"
import { Injectable } from '#angular/core';
import { Music } from '../../models/music';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataShareService {
private _sendDataSubject = new Subject<Music[]>();
$sendDataObservable = this._sendDataSubject.asObservable();
constructor() { }
sendData(data: Music[]){
this._sendDataSubject.next(data);
console.log(data);
}
}
"catalog"
import { Component, OnInit, Input } from '#angular/core';
import {RequestService} from '../../services/request/request.service';
import {DataShareService} from '../../services/dataShare/data-share.service';
import { Music } from '../../models/music';
#Component({
selector: 'catalog',
templateUrl: './catalog.component.html',
styleUrls: ['./catalog.component.sass'],
providers: [RequestService, DataShareService]
})
export class CatalogComponent implements OnInit {
public title: any;
public InfoLlegada: any;
constructor(private _dataShareService: DataShareService) {}
ngOnInit() {
console.log(this.InfoLlegada)
this._dataShareService.$sendDataObservable.subscribe(
data => {
this.InfoLlegada = data
console.log(data);
});
}
}
Not sure if this is the actual cause, but there an issue with your this binding in getMusic subscription in search component. Try this.sendData.call(this, result.results);

angular 5 behaviorsubject not working with http [duplicate]

This question already has answers here:
Angular 2 Shared Data Service is not working
(3 answers)
Closed 4 years ago.
I am trying to get user type from the server and based on the role of the user display data. The http servise is running file and returning the desired data. I have two components. Login and Home components. After login a boolean variable is set to decide if the user is Admin or User. The login function is showing isAdmin variable true. But home component is showing it as false. I am using behaviorsubject and observable to sync the data.
Service
import { Injectable } from '#angular/core';
import {Http, Response} from "#angular/http";
import {Observable} from "rxjs/Observable";
import "rxjs/Rx";
import {IPosts} from "./posts";
import {IUser} from "./user";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
#Injectable()
export class ExamService {
public isAdmin = new BehaviorSubject<boolean>(false);
cast = this.isAdmin.asObservable();
private _postsURL = "http://localhost:3292/examservice.svc/ExamQs";
private _userURL = "http://localhost:3292/examservice.svc/GetUser";
constructor(private http: Http) {
}
getPosts(): Observable<IPosts[]> {
return this.http
.get(this._postsURL)
.map((response: Response) => {
return <IPosts[]>response.json();
})
.catch(this.handleError);
}
getUser(user:string,pass:string): Observable<IUser[]> {
return this.http
.get(this._userURL+"/"+user+"/"+pass)
.map((response: Response) => {
return <IUser[]>response.json();
})
.catch(this.handleError);
}
checkAdmin(data){
this.isAdmin.next(data);
}
private handleError(error: Response) {
return Observable.throw(error.statusText);
}
}
Login Component
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { ExamService } from "../exam.service";
import {IPosts} from "../posts";
import {IUser} from "../user";
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
providers: [ ExamService ]
})
export class LoginComponent implements OnInit {
_postsArray: IPosts[];
_userArray: IUser[];
ifuser: boolean = false;
Name: string;
Pass: string;
validated: boolean = true;
constructor(private apiSerivce: ExamService,private router:Router) { }
getPosts(): void {
this.apiSerivce.getUser(this.Name,this.Pass)
.subscribe(
resultArray => {
this._userArray = resultArray;
if(this._userArray[0].Role == "Admin")
{
this.ifuser = true;
this.apiSerivce.checkAdmin(this.ifuser);
}
else
{
this.apiSerivce.checkAdmin(this.ifuser);
this.router.navigate(['']);
}
},
error => console.log("Error :: " + error)
)
console.log(this.ifuser);
this.router.navigate(['']);
}
ngOnInit(): void {
this.apiSerivce.cast.subscribe(data =>
{
this.validated = data;
console.log("Login " + this.validated);
});
}
}
Home Component
import { Component, OnInit } from '#angular/core';
import { ExamService } from "../exam.service";
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
providers: [ ExamService ]
})
export class HomeComponent implements OnInit {
validated: boolean;
constructor(private apiSerivce: ExamService) { }
ngOnInit() {
this.apiSerivce.cast.subscribe(data =>
{
this.validated = data;
console.log("Home " + this.validated);
});
}
}
I have found the solution to this problem. Do not add service as provider in the child components instead add provider in app.component.ts file which is a parent component. so instead of
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
providers: [ ExamService ]
})
it should be like this in child components
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})
and in app.component.ts file it should be like this
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ ExamService ]
})

HTTP service not working

This is my HttpService.ts
import { Injectable } from "#angular/core";
import { Http, Response } from "#angular/http";
import 'rxjs/add/operator/map';
#Injectable()
export class HttpService {
constructor (private http: Http) {}
getData() {
return this.http.get('http://blog_api.org/v1/posts')
.map((response: Response) => response.json());
}
}
This is my app.component.ts
import { Component } from '#angular/core';
import { HttpService } from '../app/services/HttpService'
#Component({
selector: 'my-app',
template: `Hello`,
})
export class AppComponent {
constructor (private httpService: HttpService) {};
ngOnInit() {
this.httpService.getData()
.subscribe(
data => console.log(data)
)
}
}
When I running app, I get error:
EXCEPTION: No provider for HttpService!
In your AppModule you should be doing:
import {HttpService} from "...";
import {HttpModule} from "#angular/http";
#NgModule({
bootstrap: [...],
imports: [HttpModule],
declarations: [...],
entryComponents: [...],
providers: [HttpService]
})
export default class AppModule{}
You must provide the HttpService in the model that loads the app.component.ts.
In your case, as you are using app.component.ts, provide the http in app.module.ts. Something like:
import { HttpService } from '../app/services/HttpService'
#NgModule({
...
providers: [
...
HttpService,
]
})
export class AppModule { }
Add
providers: [HttpService]
in #Component block

How to share service data between components correctly in Angular 2

I want to create a service to get data from .json file once and share it to multiple subscribers. But now with my solution number of requests to get data from .json file equals to a number of a subscibers for my service.
getconfig.service.ts
import {Injectable} from 'angular2/core';
import {Http, Response} from "angular2/http";
#Injectable()
export class ConfigService {
config: any;
http: Http;
constructor(http: Http) {
this.http = http;
console.log('Inside service');
this.config = this.http.get('/config.json');
}
}
robotui.component.ts
...
import {ConnectionService} from '../services/connection.service';
#Component({
...
providers: [HTTP_PROVIDERS, ConfigService, ConnectionService]
...
})
constructor(private _configService: ConfigService) {
this._configService.config.subscribe((observer) => {
console.log('Subscribe in RobotUI component', JSON.parse(observer._body));
});
}
actual.photo.component.ts
import {Component} from 'angular2/core';
import {ConfigService} from '../services/getconfig.service';
#Component({
...
providers: [ConfigService]
})
export class ActualPhotoComponent {
constructor(private _configService: ConfigService) {
this._configService.config.subscribe((observer) => {
console.log('Subscribe in ActualPhoto component', JSON.parse(observer._body));
});
}
}
When i run it in my console i see:
So, there is get request for each subscibers. I want a solution when i get config.json file only once, save this info in a service and share it with multiple subscibers.
That's because
#Component({
...
providers: [ConfigService] //<--- this creates service instance per component
})
To share data among controllers/components and to create single instance only, you have to inject your service into bootstrap function.
import {ConfigService } from './path to service';
bootstrap('AppCompoent',[configService]) //<----Inject here it will create a single instance only
In subscribing component,
robotui.component.ts
...
import {ConfigService} from '../services/getconfig.service'; //<----- Note this line here....
import {ConnectionService} from '../services/connection.service';
#Component({
...
... // No providers needed anymore
...
})
constructor(private _configService: ConfigService) {
this._configService.config.subscribe((observer) => {
console.log('Subscribe in RobotUI component', JSON.parse(observer._body));
});
}
actual.photo.component.ts
import {Component} from 'angular2/core';
import {ConfigService} from '../services/getconfig.service';
#Component({
...
... // No providers needed anymore...
})
export class ActualPhotoComponent {
constructor(private _configService: ConfigService) {
this._configService.config.subscribe((observer) => {
console.log('Subscribe in ActualPhoto component', JSON.parse(observer._body));
});
}
}
This is what you should do.

Categories

Resources