what I am trying here is to use the variables i read off the route to determine which blog to use from the json. the json file is an array of sections which further contain an array of blogs.
while the code runs perfectly if i put id1 and id2 as 1, 2 in the this.blog=data[this.id1].blogs[this.id2]; line,
I am getting an error TypeError:_data_json__WEBPACK_IMPORTED_MODULE_2___namespace[this.id1] is undefined on no change.
import { Component, OnInit } from '#angular/core';
import * as data from '../data.json';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-post',
templateUrl: './post.component.html',
styleUrls: ['./post.component.css']
})
export class PostComponent implements OnInit {
id1;
id2;
sub;
blog;
constructor(
private _Activatedroute: ActivatedRoute,
private _router: Router
) {}
ngOnInit() {
this.sub = this._Activatedroute.paramMap.subscribe(params => {
console.log(params);
this.id1 = Number(params.get('id1'));
this.id2 = Number(params.get('id2'));
this.blog = data[this.id1].blogs[this.id2];
});
}
}
also on replacing id1, id2 with any variable, i get the same error.
edit: I changed the import * as data from '../data.json'; to const data=require('../data.json'); and i got the correct result. however, i still dont understand why this happens and would like to keep the question open for same.
params.get method returns only string. You can try converting it into number before passing it to data.
Try using the line written below
this.blog = data[+this.id1].blogs[+this.id2];
Related
I have to make an Angular application in which i get data from the back-end and display it on the front-end, but with some added hard-coded data.
My communication is between 2 files:
client.service.ts
import { Injectable } from '#angular/core';
import {HttpClient, HttpHeaders} from "#angular/common/http";
import {environment} from "../environments/environment";
import {catchError, map, Observable, of} from "rxjs";
const clientUrl = environment.apiUrl+'client';
#Injectable({providedIn: 'root'})
export class ClientService {
public optional: any;
constructor(private http: HttpClient) {}
getText(): Observable<any> {
console.log("it works!");
return this.http.get(clientUrl+"/getText").pipe(map(res => {
console.log(res);
this.optional = res.toString();
}));
}
}
and the second one:
client.component.ts
import { Component, OnInit } from '#angular/core';
import {ClientService} from "../client.service";
#Component({
selector: 'app-client',
templateUrl: './client.component.html',
styleUrls: ['./client.component.css']
})
export class ClientComponent implements OnInit {
public textResponse: any;
constructor(public service: ClientService) {}
ngOnInit(): void {}
getText() {
let text: any;
this.textResponse = this.service.getText().subscribe();
console.log(this.textResponse);
text = this.textResponse + "This text is added from code.";
console.log(text);
}
}
When i call "this.http.get(clientUrl+"/getText")" I get a SafeSubscriber object, from which i managed to get the data displayed in the console using the method ".subscribe(...)" with a "console.log()" inside of it. However, i did not find any method to extract the data out of this subscribe.
As the code above shows, i have tried to use pipe and map, but the local variable is returned as [Object object], and when i print it in the console i get either undefined, either nothing.
This is what my code currently displays:
it works! [client.service.ts:33]
SafeSubscriber {initialTeardown: undefined, closed: false, _parentage: null, _finalizers: Array(1), isStopped: false, …} [client.component.ts]
[object Object]This text is added from code. [client.component.ts]
{text: 'This text is read from a file.'} [client.service.ts]
I have also tried all the suggestions found in questions below:
angular 2 how to return data from subscribe
Angular observable retrieve data using subscribe
Does anyone know a method in which i could get the data out of the Subscribe?
You are missing the return keyword when mapping the response, looking at the console.log, you need the text property
getText(): Observable<any> {
console.log("it works!");
return this.http.get(clientUrl+"/getText").pipe(map(res => {
console.log(res);
this.optional = res.toString();
return res.text;
}));
}
I am reading data from a JSON, which is one a server and it updates regularly and changes. I need to be able to read this JSON from the server so that I display the most up to date information on my web page.
Currently, the to be able to read the JSONs they are stored within the same project folder as my angular project. (This was because they were not set up on the server when I started).
This is how I currently import the JSON to be able to read it:
import jsonInfo from '../../../info.json'
I thought I would be able to change the file link to the server address, like so:
import jsonInfo from 'http://servername/folder/info.json'
But, VSCode gives me an error: Cannot find module 'http://servername/folder/info.json'
This is definitely the location of the JSON I am trying to load because when I click the link it takes me to the JSON and displays it.
My question is, how do I import the JSON into my .ts from a server so that I can keep getting the updated information from the JSON?
JSON file on a server is just like any other web resource you would try to access (like an API endpoint, for example).
So you should use built in angular http client to access this JSON file.
For example:
import { HttpClient } from '#angular/common/http';
export class SomeService {
constructor(private http: HttpClient) { }
getInfo() {
return this.http.get('http://servername/folder/info.json');
}
}
//...
export class SomeComponent implements OnInit {
info: any;
constructor(private someService: SomeService) {}
ngOnInit() {
this.someService.getInfo().subscribe(info => this.info = info)
}
}
Use HttpClient get method.
this.httpClient.get('http://servername/folder/info.json').subscribe(data => {
// your logic
})
You can use HttpClient and do like as shown below
Working Demo
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular';
data = [];
apiUrl = 'http://servername/folder/info.json';
GetData() {
this.http.get<any[]>(this.apiUrl)
.subscribe(data => {
this.data = data;
});
}
ClearData() {
this.data = [];
}
constructor(private http: HttpClient) {}
ngOnInit() {}
}
I am using routing in Angular to pull the url and store it in a global variable. It works well, except for when the url has an 'id' in it.
For example, my Url == '/site/1' however....
this.authService.current_route = this.router.url
// '/site' (not 'site/1' or 'site/:id')
How do I refactor to make this work?
My html looks like:
<span id="sitehead"> <a [routerLink]="['/site', site.id ]" (click)="changeroute()"> Site:</a></span>
My component:
import { Component, OnInit, Input } from '#angular/core';
import { DataService } from '../data.service';
import { Http } from '#angular/http';
import * as d3 from 'd3';
import { AuthService } from "../services/auth.service";
import { Router } from "#angular/router";
#Component({
selector: 'app-summary',
templateUrl: './summary.component.html',
styleUrls: ['./summary.component.css'],
})
export class SummaryComponent implements OnInit {
#Input() site;
constructor(private _dataService: DataService, private http: Http, public authService: AuthService, private router:Router ) {
}
changeroute(){
this.authService.current_route = this.router.url
console.log(this.authService.current_route)
}
Thanks!! Let me know if I can clarify
There's probably a less complicated way to get the current url, but in the past, I created a function that does it. Hopefully it suits your immediate needs.
constructor(route: ActivatedRoute) {
const path = this.getPath(route.snapshot);
}
private getPath(route: ActivatedRouteSnapshot): string {
const urlSegments = route.pathFromRoot.map(r => r.url);
return '/' + urlSegments.filter(segment => !!segment && segment.length).join('/');
}
Here is my first component
requirement:display data in second component which is sent by first component.
current status: i set data into service get set method and get also the data data but unable to display same data which is set by first component template .
import { Component } from '#angular/core';
import { ConfigService } from './myservicedata';
import { Router } from '#angular/router';// add file for navigate from one page to another page
#Component({
selector: 'tab-one',
templateUrl: './tabone.component.html',
providers:[ConfigService]
})
export class taboneComponent {
constructor(public configservice:ConfigService,private router:Router) {}
formData(data:any){
this.configservice.set_service_data(data);
console.log("value of data which is set by me into service"+ data);
}
// for navigate from one url to another url
navigate(){
this.router.navigateByUrl('/tab_two');
}
}
Here is my second component
import { Component ,OnInit} from '#angular/core';
import { ConfigService } from './myservicedata';
import 'rxjs/Rx'; // add this file for use the map feature.
#Component({
selector: 'tab-two',
templateUrl: './tabtwo.component.html',
// providers:[ConfigService]
})
export class tabtwoComponent {
public getterSetter:any=[];
// public store_service_data:any=[];
constructor(private configservice:ConfigService) {}
ngOnInit(){
this.configservice.get_service_data()
}
showdata(){
console.log( this.configservice.get_service_data());
}
};
Here is my service
import {Injectable} from '#angular/core';
import {Http,Response} from "#angular/http";
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
#Injectable()
export class ConfigService {
private _url:string="../mockData.json";
public serviceData:any=[];
get_service_data():any{
return this.serviceData;
// this.serviceData.map(
// (response:Response) => response.json()
// );
};
set_service_data(value:any):void{
this.serviceData=value;
};
constructor(private http:Http) {}
// Uses http.get() to load a single JSON file
getFriendsData():any {
return this.http.get(this._url).map(
(response:Response) => response.json()
);
}
};
Remove the providers array in your TaboneComponent and make sure ConfigService is in the providers array in your app.module.ts
Explanation:
In order to retrieve the information from the service what you want is to make sure that both your components reference the same instance on your ConfigService
Angular uses hierarchical dependency injection, which means whenever a dependency like your ConfigService is requested, Angular will traverse up the component tree to find a place where it has already been provided and pass that instance to the requester.
Because of this, you can easily create a singleton instance by providing a service in your app module as every component is a child of this.
When you provide the service like you have done in your TaboneComponent you are saying give me a new instance of this service even if one has already been provided somewhere else. Any component that is a child of tab-one will be able to get the data you have set in that service, but anything that is not a child will not.
You can read more about Angular's dependency injection here:
https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html
I am working on an app and am having difficulty using an API call to Eventbrite in a provider, parsing the JSON it returns, and inserting the data I want into an array.
Here is my provider (event-provider.ts):
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import {NativeStorage} from "ionic-native";
import 'rxjs/add/operator/map';
/*
Generated class for the EventProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class EventProvider {
constructor(public http: Http) {
console.log("Event Provider")
}
public getJsonData(){
return this.http.get('https://www.eventbriteapi.com/v3/events/search/?location.address=Atlanta&expand=organizer,venue&token=VMGQGYQUIO3IKNS75BD4').map(res => res.json().events);
}
//console.log('Hello EventProvider Provider');
}
And here is the event page in which I eventually will list the data (events.ts):
import { Component } from '#angular/core';
import {EventProvider} from '../../providers/event-provider';
import { NavController } from 'ionic-angular';
#Component({
selector: 'event-list',
templateUrl: 'events.html',
providers: [EventProvider]
})
export class EventsPage {
events = []
constructor(public navCtrl: NavController, private eventProvider: EventProvider) {
this.events = eventProvider.getJsonData();
}
}
For the above .ts file I am getting an error at this.events = eventProvider.getJsonData();. The error says: Type 'Observable' is not assignable to type 'any[]'. Property 'find' is missing in type 'Observable'. I do not really understand this error.
This is what the JSON response looks like: EventBrite
Basically, I want to add each event as an item to an array. The JSON response contains about 500 events.
I've just stuck at the moment an not sure if on on the right track. It is hard to debug my code because it is being tested in an iOS emulator and thus the console.log() doesn't work. Any tips on how to reach my goal of creating an array of events from the JSON response?
You need to subscribe to observables in order to make a request.
this.events = eventProvider.getJsonData();
should be something like:
eventProvider.getJsonData().subscribe((res)=>{
this.events = res.events;
});
And Also you need to return that json and assuming you always have event properties in the response:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import {NativeStorage} from "ionic-native";
import 'rxjs/add/operator/map';
/*
Generated class for the EventProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class EventProvider {
constructor(public http: Http) {
console.log("Event Provider")
}
public getJsonData(){
return this.http.get('yourUrl')
.map(res => {
let body = res.json();
return body.events || { };
});
}
}