Fetch the data from GITHUB API - javascript

I want to get all the data from github API. But it doesn't work for me.
My .ts file is below:
import { Component } from '#angular/core';
import { GitTakeService } from "app/git-take.service";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
user:any;
constructor(private gittakeService:GitTakeService ){
this.gittakeService.getUser().subscribe(user=>{
debugger;
this.user=user;
console.log(user);
})
}
}
My service is below:
import { Injectable } from '#angular/core';
import {Http,Response, Headers} from '#angular/http'
import'rxjs/add/operator/map';
#Injectable()
export class GitTakeService {
constructor(private http:Http) { }
getUser(){
debugger;
return this.http.get("http://api.github.com/users")
.map(
(resp:Response)=>{
return resp.json().response;
}
);
}
}
When consoling the user in .ts file, it shows undefined. My view file is like this:
{{user}}
Anyone please help me to solve this problem?

What you are receiving is an array, so you want to use resp.json() instead of resp.json().response there is no such property like response in your response. So your map should look like this:
getUser(){
debugger;
return this.http.get("http://api.github.com/users")
.map((resp:Response)=>{
return resp.json();
});
}
and in your component I would name the array users instead of user, since there are several users in your response. Also I suggest you keep anything unnecessary from the constructor and use OnInit instead:
users = [];
constructor(private gittakeService:GitTakeService ){ }
ngOnInit() {
this.gittakeService.getUser()
.subscribe(data => {
this.users = data;
});
}
Then you can iterate the array and use the property names to show the properties of one user object:
<div *ngFor="let user of users">
{{user.login}}
</div>

resp.json().response is undefined resp.json() is what you want
the service function:
getUser(){
return this.http.get("http://api.github.com/users")
.map(
(resp:Response)=>{
return resp.json();
}
);
}`
and the component:
this.gittakeService.getUser().subscribe(users=>{
this.user=users[0];
console.log(user);
})

Related

how do i assign data from the subscribe call to a local variable in Angular

I have tried to declare the variable inside the ngOnInit() but it goes out of scope. I would like to use the variable to iterate over the data and populate my html component. I have followed the answered questions on the same issue but most of them suggest calling a function inside the subscribe function, unfortunately in my case i just need to view the returned data.
import { Component, OnInit } from "#angular/core";
import { Playlist } from "../playlist";
import { PlaylistService } from "../playlist.service";
#Component({
selector: "app-market-place",
templateUrl: "./market-place.component.html",
styleUrls: ["./market-place.component.css"],
})
export class MarketPlaceComponent implements OnInit {
_playList: Playlist[] = []; //never gets assigned here
errorMessage;
constructor(private playListService: PlaylistService) {}
ngOnInit() {
this.playListService.getPlaylist().subscribe({
next: (playList) => {
this._playList = playList;
console.log(this._playList); // am able to log the data but its never assigned to my _playList variable
},
error: (err) => (this.errorMessage = err),
});
}
}
here is the service class
import { Injectable } from "#angular/core";
import {HttpClient, HttpErrorResponse} from '#angular/common/http'
import { Observable, throwError } from "rxjs";
import {catchError, map, tap} from 'rxjs/operators'
import { Playlist } from "./playlist";
#Injectable({
providedIn: "root",
})
export class PlaylistService {
private playListUrl = "https://reqres.in/api/users";
constructor(private http: HttpClient) {}
getPlaylist():Observable<Playlist[]> {
return this.http.get<Playlist[]>(this.playListUrl).pipe(
map((response) => <Playlist[]>response),
catchError(this.handleError),
);
}
private handleError(err:HttpErrorResponse){
let errorMessage = '';
if (err.error instanceof ErrorEvent){
errorMessage = `An error occurred: ${err.error.message}`
}else {
errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
}
console.error(errorMessage);
return throwError(errorMessage)
}
}
I do not know, what your Playlist object looks like, but maybe I have a simple idea, that could solve your issue. I suppose that console.log can not show the array of your objects. Did you try the following?
console.log(this._playList[0]);

await fetch Angular between components via Input

I'm making a request with fetch to the reqres api users in app.component, then i share data to his child component (hello.component) via Input. I get the correct user names in child template, I'm trying to print the users in console but i get an empty array. It's there a way to 'await' the response of another component? i guess this is an asynchronous issue. Here is the link: https://stackblitz.com/edit/angular-ivy-b3m1kp?file=src%2Fapp%2Fhello.component.ts
Thanks in advance.
app.component:
import { Component, VERSION, OnInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public usuarios;
constructor(){
this.usuarios = [];
}
ngOnInit(){
this.getUsers();
}
getUsers(){
fetch('https://reqres.in/api/users')
.then(data => data.json())
.then(users => {
this.usuarios = users.data;
console.log(this.usuarios);
});
}
}
hello.component:
import { Component, Input, OnInit } from '#angular/core';
#Component({
selector: 'hello',
template: `<h1 *ngFor="let user of usuarios">Hello {{user.first_name}} </h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent{
#Input() usuarios;
ngOnInit(){
console.log(this.usuarios);
}
}
app.component.html:
<hello [usuarios]="usuarios"></hello>
As the fetch operation is asynchronous, usuarios array would be empty upon initialization for the child. To detect the value changes move logic which will use the fetched results to ngOnChanges.
Like this:
ngOnChanges(changes: SimpleChanges) {
const { previousValue, currentValue } = changes.usuarios;
if (previousValue !== currentValue) {
console.log(this.usuarios);
}
}
Having a condition to check if the value has changed inside ngOnChanges is essential, otherwise the logic will be constantly triggered.
<hello *ngIf="usuarios.length>0" [usuarios]="usuarios"></hello>
<p>
Start editing to see some magic happen :)
</p>

Can't get deeper into the response data object in subscribe's callback function. Why?

I'm fetching data from RandomUser api with Angular HttpClient. I've created a method in a service calling GET, mapping and returning a Observable. Then I subscribe on this method in a component importing this service and in subscribe's callback I am trying to store the response data in a local variable. The problem is I can't get "deeper" into this response object than:
this.randomUser.getNew().subscribe(data => {
this.userData = data[0];
})
If I'm trying to reach any further element of that response object, and log it to console it I get "undefined". To be precise I cant reference to, for example:
this.randomUser.getNew().subscribe(data => {
this.userData = data[0].name.first;
})
If I store the "data[0]" in a variable first I can get into these unreachable properties. What is the reason of it? Please, help. Let me know what important piece of fundamental JS (or Angular) knowledge I'm not aware of. As far as I know I should be able to do what I am trying to do :)
service looks like these
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class RandomUserService {
url: string = " https://randomuser.me/api/ "
constructor(private http: HttpClient) { }
public getNew(): Observable<any> {
return this.http.get(this.url)
.pipe(map(responseData => {
const returnDataArray = [];
for (const key in responseData) {
returnDataArray.push(responseData[key])
}
return returnDataArray;
}))
}
}
component looks like these:
import { Component, OnInit } from '#angular/core';
import { RandomUserService } from 'src/app/shared/random-user.service';
import { Observable } from 'rxjs';
#Component({
selector: 'app-single-character',
templateUrl: './single-character.component.html',
styleUrls: ['./single-character.component.scss']
})
export class SingleCharacterComponent implements OnInit {
userData: object;
fname: string;
constructor(private randomUser: RandomUserService) {
this.randomUser.getNew().subscribe(data => {
this.userData = data[0];
})
}
ngOnInit(): void {
}
}
You are not parsing the returned data correctly in getNew().
The returned data looks like this:
So you need to access the user data like:
this.randomUser.getNew().subscribe(data => {
this.userData = data[0][0]; // note 2nd [0]
})
or for first name:
this.randomUser.getNew().subscribe(data => {
this.userData = data[0][0].name.first;
})
See stackblitz here: https://stackblitz.com/edit/so-http-parse?file=src/app/app.component.ts

How to get first value and then another subscribe method

I have developed a simple angular 7 web app. firebase database connectivity,
I am trying to store the first list in an array using the subscribe method and then console.log that array.
but before that data get the array will print undefined after some time it will get data.
How can code wait for the response is done and then print that array.
import { Injectable } from '#angular/core';
import { AngularFireList, AngularFireDatabase } from 'angularfire2/database';
#Injectable({
providedIn: 'root'
})
export class DressesService {
constructor(public firebase: AngularFireDatabase) { }
getJoinDresses(){
return this.firebase.list('makavana-tailor/dresses').snapshotChanges()
}
}
import { Component, OnInit } from '#angular/core';
import { DressesService } from '../../services/dresses/dresses.service';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
#Component({
selector: 'app-con-dress',
templateUrl: './con-dress.component.html',
styleUrls: ['./con-dress.component.css']
})
export class ConDressComponent implements OnInit {
constructor(private dresses: DressesService) { }
dressArray = [];
ngOnInit() {
this.getAllDresses();
console.log(this.dressArray)
}
getAllDresses(){
this.dresses.getJoinDresses().subscribe(actions => {
this.dressArray = actions.map(action => {
return {
$key: action.key,
...action.payload.val()
}
})
})
}
}
Your question title is not clear. But if I understand your problem correctly, you are facing an issue in working with asynchronous calls. Either you have to print console.log(this.dressArray) inside the subscribe or return the observable data from getAllDresses and subscribe to it within onInit()
code :
ngOnInit() {
this.getAllDresses().subscribe(data => {
this.dressArray = data;
console.log(this.dressArray)
});
}
getAllDresses(){
return this.dresses.getJoinDresses().pipe(map(actions => {
return actions.map(action => {
return {
$key: action.key,
...action.payload.val()
}
})
}))
}
The problem with your current code is that you show the array before it has a chance to be populated.
You know it's populated when the subscribe function is called.
So the easiest is to modify your code by moving the console.log inside the subscribe call:
ngOnInit() {
this.getAllDresses();
}
getAllDresses(){
this.dresses.getJoinDresses().subscribe(actions => {
this.dressArray = actions.map(action => ({
$key: action.key,
...action.payload.val()
}));
console.log(this.dressArray);
})
}

cant pass data from AppComponent to function

I send the email data to this.user in constructror.
So it storage in AppComponent, Next i need this variale in function getUserData for import some data...
but the console.log show undefined, and there is also error for users :
Cannot read property 'auth' of undefined
So what i made wrong? Why i cant pass data using this.?
Update
Now the user.String is string that contain a "xxxx#.xx.com"
But still i cant pass it there. this.user in getUserData is undefind :/
import { Component, OnInit } from '#angular/core';
import { RewardsComponent } from './rewards/rewards.component';
import { AngularFire,AuthProviders, AuthMethods, FirebaseAuthState } from 'angularfire2';
import { Router } from '#angular/router'
declare var firebase: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app works!';
userData: any = [];
user: String;
constructor(public af: AngularFire, private router: Router) {
af.auth.subscribe(auth => {
if(auth) {
this.user = auth.auth.email.toString();
}
})
}
ngOnInit() {
this.getUserData();
}
getUserData() {
var ref = firebase.database().ref("/user");
ref.orderByChild("email").equalTo(this.user).on("child_added", (snapshot) => {
this.userData.push(snapshot.val());
});
}
}
Probably
this.user = auth.auth.email;
is storing a string, something like 'someemail#gmail.com'
When you try to access
this.user.auth
there is no .auth attribute/key, because this.user is not an object.
Also, you have to keep in my mind that af.auth.subscribe is assynchronous code, therefore you can't access this.user in the ngOnInit method, because you don't know if the af.auth.subscribe has been called yet.
You should access email since you are assigning only email ,
console.log(this.user.email);
var users = this.user.email;
if you need to access the whole auth object, then assign it as,
this.user = auth;

Categories

Resources