I am trying to make a simple HTTP GET request using angular 2 with Typescript. I am getting a 404 error, with a null url. Shown below is my component file, and the error I am receiving.
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { BreadcrumbService } from './breadcrumbService';
import { Http, Response } from '#angular/http';
#Component({
moduleId: module.id,
providers: [ BreadcrumbService],
templateUrl: 'html/appList.html',
styleUrls: ['css/list.css']
})
export class HealthComponent {
constructor(private http: Http) {
this.http.get('http://jsonplaceholder.typicode.com/posts/1')
.toPromise()
.then((res: Response) => {
console.log('RES: ', res);
})
.catch((err: Error) => {
console.log('ERR!!: ', err);
});
}
}
The error message:
Response {_body: Object, status: 404, ok: false, statusText: "Not Found", headers: Headers…}
_body:Object
headers:Headers
ok:false
status:404
statusText:"Not Found"
type:2
url:null
__proto__:Body
This is probably InMemoryWebApiModule.forRoot related issue. This happens when you load in-memory api, but trying to reach undefined url. The way to solve this is by setting passThruUnknownUrl: true in app.module config:
InMemoryWebApiModule.forRoot(InMemoryDataService, {passThruUnknownUrl: true}) ..
As you can see, it's a 404 error, analyse your request to the server. 404 error means that what you requested wasn't found.
About how you make the request, try ti use .map instead of toPromise.
Try to not make HTTP requests on the constructor, use ngOnInit instead.
Related
I'm a total newbie into Angular/Typescript web development.
I'm developing a website using ASP.NET Core 2.0 and Angular 4. It needs to fetch some data and present it at the homepage (that would be the home component of the Angular app). I've seen some examples and they suggest doing something like this:
import { Component, Inject } from '#angular/core';
import { Http } from '#angular/http';
#Component({
selector: 'quotes',
templateUrl: './quotes.component.html'
})
export class FetchDataComponent {
public quotes: Quote[];
constructor(http: Http, #Inject('BASE_URL') baseUrl: string) {
http.get(baseUrl + 'api/quotes/recent').subscribe(result => {
this.quotes = result.json() as Quote[];
}, error => console.error(error));
}
}
interface Quote {
text: string;
author: string;
timeStamp: Date;
}
That code works fine when the component is not the first one to be presented when the page is loaded. If I try to fetch data on the home component, the server freaks out and throws all kind of exceptions. First, it throws a TaskCancelledException, and further requests throw:
NodeInvocationException: Prerendering timed out after 30000ms because the boot function in 'ClientApp/dist/main-server' returned a promise that did not resolve or reject.
I'm assuming that I'm doing stuff very wrong, but I haven't seen any other way of doing what I want.
I tried moving the offending code (the http.get request) to a separate function, but now I don't know how am I supposed to call it when the component finished loading.
import { Component, Inject } from '#angular/core';
import { Http } from '#angular/http';
#Component({
selector: 'quotes',
templateUrl: './quotes.component.html'
})
export class FetchDataComponent {
public quotes: Quote[];
private ht: Http;
private url: string;
constructor(http: Http, #Inject('BASE_URL') baseUrl: string) {
this.ht = http;
this.url = baseUrl;
}
fetchQuotes(): void {
this.ht.get(baseUrl + 'api/quotes/recent').subscribe(result => {
this.quotes = result.json() as Quote[];
}, error => console.error(error));
}
}
interface Quote {
text: string;
author: string;
timeStamp: Date;
}
No http event has helped me. I can make everything work using the (click)="" directive, but obviously, I don't want the user to have to click something for the app to work as expected. No other directive seems to work either.
Below is the code I have on the html of the component:
<p class="warning" *ngIf="!quotes" (click)="fetchQuotes()">
<span class="glyphicon glyphicon-warning-sign"></span>
<em>There's nothing to show yet.</em>
</p>
<div *ngIf="quotes">
<ul class="quoteList" *ngFor="let quote of quotes">
<li>
{{ quote.text }}
<small>{{ quote.author }}, {{ quote.timeStamp }}</small>
</li>
</ul>
</div>
So to summarize, I need a way to fetch data for the component that Angular will show by default upon loading the page.
So to summarize, I need a way to fetch data for the component that
Angular will show by default upon loading the page.
The typical way to do this is to implement the Angular OnInit interface, which allows you to do initialization in the ngOnInit() callback method.
import { OnInit } from "#angular/core";
// ...
export class FetchDataComponent implements OnInit {
ngOnInit() {
// do initial data load here
}
}
I am getting below error when using HTTP service in angular2 with localhost WEB Api. When using URL directly in browser it is working fine and returning JSON result.
An error occurred Response with status: 404 Not Found for URL: null
import { Headers, Http } from '#angular/http';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class QuizDalService {
private quizquestionUrl = 'http://localhost:59786/api/AngularQuiz';
constructor(private http: Http) { }
getQuizQuestions(name: string): Promise<mcquestion[]>{
return this.http.get(this.quizquestionUrl)
.toPromise()
.then(response => response.json().data as mcquestion[])
.catch(this.handleError);
}
}
Please let me know if I am missing anything.
The code listed in (A) never sends its HTTP request when test() is called whereas the almost identical code in (B) does work. Any idea what the problem is? I know whether the request is sent by watching the server logs. Also, if I make the request in (A) manually by pasting it into the browser, I get the expected response. I'm stumped!
(A)
import { Constants } from '../toplevel/constants'
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
#Injectable()
export class SigninService {
constructor (private http: Http, private constants : Constants) {
}
getToken(username: string, password: string) : Observable<string>{
var url = `${this.constants.apiRoot}/users/${username}?${password}`
console.log(`Calling api server with url ${url}`)
return this.http.get(url)
.map((res:Response) => JSON.stringify(res.json()))
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
test() {
this.getToken('jc', 'yadayada')
}
}
(B: excerpt)
getDocument(id: string) : Observable<Document>{
return this.http.get(`${this.apiUrl}/documents/${id}`)
.map((res:Response) => new Document(res.json()['document']))
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
Your sequence is cold. You need to change your test to:
this.getToken('jc', 'yadayada').subscribe()
to make it active and send the request
AngularJs 2 with Webpack.
I am not able to connect to NYT Api.
ALL ENDOPOINTS TESTED AND WORKING PROPERLY
AngularJs 2 in production mode:
enableProdMode();
App:
-1 component
-1 Service
All other components working/displaying properly.
No other services on app yet.
Service returns with error: (in console)
error: "Collection 'topstories' not found"
The Service
import { Injectable } from '#angular/core';
import { Http, Headers, URLSearchParams, Response } from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs';
#Injectable()
export class NewsService {
private topStoriesUrl: string = `https://api.nytimes.com/svc/topstories/v2/politics.json`;
// private topStoriesUrl: string = `https://newsapi.org/v1/articles`;
// Injecting Http capabilities
constructor( private http: Http ) {}
// for error handling
private handleError(error: any): Promise<any>{
console.error("FromSERVICE:::---:::--> ", error);
return Promise.reject( error.message || error );
}
getNews(): Observable<any> {
let parms: URLSearchParams = new URLSearchParams();
parms.set("api-key", "184db335652341518bea3e4a5db85494");
// parms.set("source", "associated-press");
// parms.set("apiKey", "e4e2aa62a883464a87547e8de4336f61");
return this.http.get( this.topStoriesUrl, { search: parms } )
.map( (res: Response) => res['articles'] )
.catch( this.handleError );
}
}
The Component
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Observable } from 'rxjs';
// service for fetcing news from api
import { NewsService } from '../services/news.service';
#Component({
selector: 'main-news',
templateUrl: '../templates/main-news.component.html'
})
export class MainNewsComponent implements OnInit{
private news: Observable<any>;
constructor(
private router: Router,
private newsService: NewsService
) {}
ngOnInit(): void {
this.newsService.getNews().subscribe( {
next: r => this.news = Observable.of<any[]>(["one"]),
error: err => console.error("From COMPONENT--->", err)
} );
}
}
I have tried this call with both Api from different organizations to get
the same error on the URL resource.
I have tried this same call with said URL with a Ruby script (NET/http) and also directly on the browser address bar, to receive a VALID response on these BOTH cases.
NOT SURE WHY IT FAILS WITH ANGULAR.
HELP!!!
From your console error it looks like the url is not found on server.
The error displayed is returned from server its not angularjs specific error.
Notice 404 not found returned.
So check your url and server again.
Turns out I was missing the:
Access-control-allow-origin
header.
Go figure!
Apparently, it is not added automatically by AngularJs 2.
Thanx
XMLHttpRequest cannot load http://localhost:8080/adminUser/login. Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
error_handler.js:48 EXCEPTION: Response with status: 0 for URL: null
server has supported CORS...but I still get this.
the code
import {Injectable} from "#angular/core";
import {Http, Headers} from "#angular/http";
import { getUserApi } from "../../../api.config";
#Injectable()
export class UserService {
constructor(public http: Http) {
}
login(userName, password) {
return this.http.post(getUserApi, {userName: userName, password:password})
.map(res => res.json());
}
}
The header of 'Access-Control-Allow-Origin': '*' should be in the server response headers not in the request header.