Ionic 3 RSS read with rss2json "Unprocessable Entity" - json

I'm having trouble converting RSS to JSON using the rrs2json API with Ionic 3. If I execute the code it gives me the error --> Response {_body: "{" status ":" error "," message ":" rss_url parameter is required."} ", Status: 422, ok: false, statusText:" Unprocessable Entity "}
Code:
noticies.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { RssProvider } from '../../providers/rss/rss';
#IonicPage()
#Component({
selector: 'page-noticies',
templateUrl: 'noticies.html',
})
export class NoticiesPage {
rssDataArray: any = [];
constructor(public navCtrl: NavController, public navParams: NavParams, public rssProvider: RssProvider) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad NoticiesPage');
this.Get_RSS_Data()
}
Get_RSS_Data(){
this.rssProvider.GetRSS().subscribe(
data => {
this.rssDataArray = data;
console.log(data);
}
);
}
}
providers --> rss --> rss.ts
import { Injectable } from '#angular/core';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class RssProvider {
constructor(public http: Http) {
console.log('Hello RssProvider Provider');
}
GetRSS(){
const RSS_URL: any='http://rss.cnn.com/rss/edition.rss';
const API: any='XXXXXXXXXXXXXX';
const count: any =20;
const API_URL: any ='https://api.rss2json.com/v1/api.json';
const response = this.http.post(API_URL, {'rss_url': RSS_URL,'api_key': API, 'count': count}).map(res => res.json());
return response;
}
}
Error -->
Error

Alright. I registered myself with the rss2json service and made sure this solution actually works (you can see the data in console).
The issue you have is that you are not using a proper way to form http request with HttpParams.
Here is working stackblitz that uses my key: https://stackblitz.com/edit/ionic-jdwqjg
now some details:
when you configure a URL using rss2json it basically adds parameters to the original URL, example:
https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Ftechcrunch.com%2Ffeed%2F&api_key=q5ijkolkdjk3urzrcfaehxeoimxr3tdu5ieiqcrq&order_by=pubDate&order_dir=asc&count=20
So in Angular/Ionic you need to leverage Angular's HttpParams to properly form request, here is your provider code with HttpParams:
provider code:
import { Injectable } from '#angular/core';
import { HttpClient, HttpParams } from '#angular/common/http';
#Injectable()
export class RssProvider {
private API_URL: string;
constructor(public http: HttpClient) {
this.API_URL = "https://api.rss2json.com/v1/api.json";
}
GetRSS() {
const params = { params: new HttpParams().set('rss_url', 'http://rss.cnn.com/rss/edition.rss').set('api_key','q5ijkolkdjk3urzrcfaehxeoimxr3tdu5ieiqcrq').set('order_by', 'pubDate').set('order_dir', 'asc')
}
return this.http.get(this.API_URL, params);
}
}

Related

Angular 'Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.'

I'm creating an Angular app which shows list of projects and list of users from postgresql database, but I'm having issues with showing list of users in html.
The problem is that Angular is considering my array as an object no matter what I do.
The same code worked for projects but didn't work for users.
This is my service:
import { environment } from "../../../environments/environment";
import { Observable } from 'rxjs';
import { Projet } from '../modele/projet.model';
import { Test } from '../modele/test.model';
import { HttpParams,HttpClient } from "#angular/common/http";
import { Injectable } from "#angular/core";
import { map } from 'rxjs/operators';
import { User } from '../modele/user.model';
import { Financement } from '../modele/financement.model';
#Injectable()
export class WebService {
constructor(private httpClient: HttpClient) { }
serverUrl: string = "http://localhost:8080/"
get(url: string): Observable<any> {
return this.httpClient.get(this.serverUrl + url);
}
}
The component :
import { Component, OnInit } from '#angular/core';
import { User } from '../../shared/modele/user.model';
import { Router } from '#angular/router';
import { WebService } from '../../shared/sevices/web.service';
import { FormGroup, FormBuilder, FormControl, Validators, Form } from '#angular/forms';
#Component({
selector: 'app-show-users',
templateUrl: './show-users.component.html',
styleUrls: ['./show-users.component.scss']
})
export class ShowUsersComponent implements OnInit {
ngOnInit(): void {
this.getData();
}
usersList: Array<User>
user: User
myForm: FormGroup;
constructor(private webService: WebService, private formBuilder: FormBuilder,private router: Router) { }
getData(): void {
this.webService.get("showUsers").subscribe(res => {
let response = JSON.parse(JSON.stringify(res))
this.usersList = response.data
})
}
}
The html :
<tr *ngFor="let user of usersList">
<td>{{user.name}}</td>
<td>{{user.username}}</td>
<td>{{user.email}}</td>
</tr>
This is the server response :
server response
NB: the EXACT same code worked for the object PROJECT
You need to make sure that the variable you pass into *ngFor is an array. You can make sure of this with Array.from(v) and can also strip any keys of an Object that might be sent from the serverside with Object.values(v):
this.webService.get("showUsers").subscribe(res => {
this.usersList = Array.from(Object.values(res.data.body.data));
})
In my case, I have a simple approach, but I spent a lot of time. You could try this:
datas: any;
this.token = JSON.parse(window.localStorage.getItem('token'));
this.authService.getData(this.token.id).subscribe(data => {
this.datas = data;
})
In the HTML template just use this.datas.id, this.datas.username instead of an *ngFor
You don't need this code:
let response = JSON.parse(JSON.stringify(res))
this.usersList = response.data
simply use:
this.userlist = res
Youe complete method:
this.webService.get("showUsers").subscribe(res => {
this.userlist = res
});

IONIC API Undefined

I have an IONIC APP with CORDOVA. I Just want to GET a JSON from an URL.
I Created a service call rest.service.ts
rest.service.ts
import { Injectable } from '#angular/core';
import { HTTP } from '#ionic-native/http/ngx';
#Injectable({
providedIn: 'root'
})
export class RestService {
BASE_URL = 'http://whatever.....';
constructor(public http: HTTP) {}
getProjects() {
const URL = this.BASE_URL + 'getProjects';
this.http.get(URL, {}, { 'Content-Type': 'application/json' })
.then(answer => {
return JSON.parse(answer.data);
})
.catch(error => {
console.log(error.status);
console.log(error.error); // error message as string
console.log(error.headers);
});
}
}
Here in this file I can see the info. If I insert something like...
console.log(JSON.parse(answer.data));
I can see the results in JSON just as I Want.
The problem is when I try to use this methods in other files...
otherpage.page.ts
import { Platform } from '#ionic/angular';
import { RestService } from './../rest.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-otherpage',
templateUrl: './otheropage .page.html',
styleUrls: ['./otherpage .page.scss']
})
export class OtherPage implements OnInit {
projects;
constructor(
public platform: Platform,
public rest: RestService,
) {
this.projects = this.rest.getProjects();
console.log(this.projects); // UNDEFINED
}
ngOnInit() { }
}
Here... this.projects... is undefined... ¿What is happening? I tried platform.ready, insert in ngOnInit... nothing works.
You need to modify the service and subscribe this service your page.
BASE_URL = 'http://whatever.....';
getProjects() {
const URL = this.BASE_URL + 'getProjects';
return this.http.get(URL, {}, { 'Content-Type': 'application/json' });
}
Subscribe this service observable in your page.ts file.
this.rest.getProjects().subscribe((answer)=>{
this.projects = JSON.parse(answer.data);
console.log(this.projects); // here you get the json
},error=>{
consoole.log(error)
});
Note:
console.log(this.projects); // UNDEFINED
Because this line executes before the http observable send the response, you need to subscribe that http observable to get the json.

Console.log to html element - Angular 4

Simple question. I have the following response from web service and I am observing it on chrome console. How do I deploy this onto Html element in angular 4? I tried to convert into JSON, but I encountered with another problem so I just decided to go with what I received after parseString.
All I want to do is, to display those fields in html element using Angular. For now, I just have component.ts file and trying to do something in html but can't figure out.
import { HttpClient, HttpErrorResponse, HttpHeaders } from '#angular/common/http';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { Observable } from 'rxjs/Observable';
import { RequestOptions, Response } from '#angular/http';
import { Injectable } from '#angular/core';
import { parseString } from 'xml2js'
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
//import { IMovie } from './movie';
#Injectable()
export class AppService {
private urlNorth = 'service';
constructor(private http: HttpClient) { }
getMovies(): Observable<any[]> {
const headers = new HttpHeaders();
headers.set('Content-Type', 'text/sml');
headers.set('Accept', 'text/xml');
headers.set('Content-Type', 'text/xml');
return this.http.get<any[]>(this.urlNorth, { headers })
.map(res => {
var result = res.text().replace('<string xmlns="service">', '').replace('</string>', '').replace(/</g, '<').replace(/>/g, '>');
parseString(result, (err, resultN) => {
if (err) {
return console.dir('invalid XML');
}
else {
console.log(resultN);
}
})
})
.catch(this.handleError);
}
private handleError(err: HttpErrorResponse): ErrorObservable {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
const errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
console.error(errorMessage);
return Observable.throw(errorMessage);
}
}
Log data
This code:
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
Does not belong in your service file. This is a component decorator and it should be on your component. Like this:
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private _appService: AppService) { }
getProduction() {
this._appService.getProduction()
}
}
Then your index.html file should use the tag to display the HTML.
In looking at your code more closely, there are other issues as well. For example, you are calling getProduction two times. You should not be calling it from the service constructor.
Also, the subscribe should be in the component, not the service.
And you should be using Http OR HttpClient, not both.
And TestBed is only for use in tests ... not in services.
I have a more complete example of a working component/service here: https://github.com/DeborahK/Angular-GettingStarted in the APM-Final folder. Consider looking through that code (or starting with that code) and making adjustments as needed for your application.
Here is a working service. (Without a plunker I can't successfully show this with your code. So you will need to make the appropriate replacements for your example.)
Service
import { Injectable } from '#angular/core';
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import { IMovie } from './movie';
#Injectable()
export class MovieService {
private moviesUrl = './api/movies/movies.json';
constructor(private http: HttpClient) { }
getMovies(): Observable<IMovie[]> {
return this.http.get<IMovie[]>(this.moviesUrl)
.do(data => console.log(JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(err: HttpErrorResponse): ErrorObservable {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
const errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
console.error(errorMessage);
return Observable.throw(errorMessage);
}
}
Component:
import { Component, OnInit } from '#angular/core';
import { IMovie } from './movie';
import { MovieService } from './movie.service';
#Component({
templateUrl: './movie-list.component.html',
styleUrls: ['./movie-list.component.css']
})
export class MovieListComponent implements OnInit {
movies: IMovie[];
errorMessage: string;
constructor(private movieService: MovieService) { }
ngOnInit(): void { this.getMovies(); }
getMovies(): void {
this.movieService.getMovies()
.subscribe(
(movies: IMovie[]) => this.movies = movies,
(error: any) => this.errorMessage = <any>error);
}
}

Angularjs 4 HTTP Get request to json file

I have the folowing problem, i cant load the data from json.
What I'm trying to do is access the given file address and spell the data but something does not load I tried and without async
driver-list.service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
#Injectable()
export class DriversListService {
private baseUrl: string = 'http://ergast.com/api/f1/2016/driverStandings.json';
constructor(private http : Http){}
data
getDriver() {
return this.http.get(this.baseUrl)
.map(res => this.data = res.json())
}
}
drivers-list-page.component.ts
import { Component, OnInit } from '#angular/core';
import { DriversListService } from '../drivers-list-page/drivers-list.service'
#Component({
selector: 'app-drivers-list-page',
templateUrl: './drivers-list-page.component.html',
styleUrls: ['./drivers-list-page.component.sass']
})
export class DriversListPageComponent implements OnInit {
drivers = []
constructor(private driverListServices: DriversListService) {}
ngOnInit(){
this.driverListServices.getDriver().subscribe(resDriverData=>this.drivers=resDriverData)
}
}
drivers-list-page.component.html
WORK
<ul class="items">
<li *ngFor="let driver of drivers | async">
<span>{{driver}}</span>
</li>
</ul>
enter image description here
Check the console log, to know more about the error...
then we can help you exactly
or try ...
import { Component, OnInit, Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import { environment } from '../../environments/environment';
import 'rxjs/add/operator/map';
#Component({
selector: 'app-searcher',
templateUrl: './searcher.component.html',
styleUrls: ['./searcher.component.css']
})
#Injectable()
export class SearcherComponent implements OnInit {
// Pixabay API Key
private key:string = environment.PIXABAY_API_Key;
// API Url
url:string;
// Array of result
images:any[];
// Result per page
per_page:number;
// User query
query:string;
constructor(private result: Http) {
}
ngOnInit() {
}
// Get http result
letSearch(query){
this.url = "https://pixabay.com/api/?key=" + this.key + "&q=" + query;
return this.result.get(this.url).map(res => res.json()).subscribe(
data => console.log(data),
error => console.log(error),
() => console.log("Fine !")
);
}
}

Parse Json from file

I have service to parse json
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import { Observable } from 'rxjs/Rx';
#Injectable()
export class TestService {
private tsUrl = './../Test/test.json';
data: Object;
constructor(private http: Http) {}
getTest(): Observable<any> {
return this.http.get(this.tsUrl)
.map(res => res.json());
}
}
But When I call this in my component
private p: any;
constructor(private testService : TestService ) {
this.p =this.testService .getTest().subscribe(
data => {
console.log(data);
};
console.log(this.p);
}
it logs:
What can I do?
And am I doing parse from json file right? File path is correct
#echonax solved my problem but now I see this error message