Running Angular 4 app using a JSON server - json

I'm trying to run an Angular 4 app while trying to use a JSON server that it has been coded with. The problem I'm having is that I don't understand how an Angular 4 app running on port 4200 can communicate with the JSON server on port 3000 at the same time. The app is an example of CRUD but when I try to add something, nothing gets posted.
This is my article.service.ts:
#Injectable()
export class ArticleService {
//URL for CRUD operations
articleUrl = "http://localhost:3000/articles";
//Create constructor to get Http instance
constructor(private http:Http) {
}
//Fetch all articles
getAllArticles(): Observable<Article[]> {
return this.http.get(this.articleUrl)
.map(this.extractData)
.catch(this.handleError);
}
//Create article
createArticle(article: Article):Observable<number> {
let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: cpHeaders });
return this.http.post(this.articleUrl, article, options)
.map(success => success.status)
.catch(this.handleError);
}
//Fetch article by id
getArticleById(articleId: string): Observable<Article> {
let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: cpHeaders });
console.log(this.articleUrl +"/"+ articleId);
return this.http.get(this.articleUrl +"/"+ articleId)
.map(this.extractData)
.catch(this.handleError);
}
//Update article
updateArticle(article: Article):Observable<number> {
let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: cpHeaders });
return this.http.put(this.articleUrl +"/"+ article.id, article, options)
.map(success => success.status)
.catch(this.handleError);
}
//Delete article
deleteArticleById(articleId: string): Observable<number> {
let cpHeaders = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: cpHeaders });
return this.http.delete(this.articleUrl +"/"+ articleId)
.map(success => success.status)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body;
}
private handleError (error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.status);
}
}
This is my db.json:
{
"articles": [
{
"id": 1,
"title": "Android AsyncTask Example",
"category": "Android"
}
]
}

I have backend service running on port 5005, and app running on 4200, in order to "talk" with each other I have set up proxy.config.json file which looks like this
{
"/api/*":{
"target":"http://localhost:5005",
"secure": false,
"logLevel": "debug"
}
}
and when I serve my app I run
ng serve -open --sourcemap=false --proxy-config proxy.config.json command.
You can also try to do something like this.

Related

i cant fix the .map on http post client

public postForObjecty(endpoint: any, data: any) {
return new Promise((resolve, reject) => {
let url = this.createBasicUrl(endpoint);
let _data = this.arrangeData(data);
let headers: any = new Headers()
let token = `Bearer ${RestProvider.BEARER_TOKEN}`;
headers.append('Authorization', token);
this.http.post(url, _data, { headers: headers })
.map((res: { json: () => any; }) => res.json())
.subscribe((data: unknown) => {
resolve(data);
}, (err: any) => {
reject(err);
});
});
}
i want to post and get methond to backend but i cant fix this code
.map
this doesnt work,
if i could fix this .map method it will be done
You want to use RxJS map method.
For that you need to .pipe the observable stream like so:
public postForObjecty(endpoint: any, data: any) {
return new Promise((resolve, reject) => {
let url = this.createBasicUrl(endpoint);
let _data = this.arrangeData(data);
let headers: any = new Headers()
let token = `Bearer ${RestProvider.BEARER_TOKEN}`;
headers.append('Authorization', token);
this.http.post(url, _data, { headers: headers })
.pipe(map((res: { json: () => any; }) => res.json()))
.subscribe((data: unknown) => {
resolve(data);
}, (err: any) => {
reject(err);
});
});
}
By default the Angular HttpClient will handle processing the JSON response for you. Assuming you are using this service, this means your map here is not necessary and can be removed entirely.
public postForObjecty(endpoint: any, data: any) {
return new Promise((resolve, reject) => {
let url = this.createBasicUrl(endpoint);
let _data = this.arrangeData(data);
let headers: any = new Headers()
let token = `Bearer ${RestProvider.BEARER_TOKEN}`;
headers.append('Authorization', token);
this.http.post(url, _data, { headers: headers })
.subscribe((data: unknown) => {
resolve(data);
}, (err: any) => {
reject(err);
});
});
}
If you do need the full response, such as the HTTP status code you can pass observe: 'response' into the options object the post function accepts. The Angular documentation goes into good detail on this.
As an FYI, in older versions of Angular that had a now deprecated service called Http and you would need to call .json() all the time.

Angular 6 - get csv response from httpClient

Can any one please give an example of fetching application/octet-stream response from angular 6 httpClient. I am using the below code and it doesn't work ( I get unknown error - 401 response) -
import { saveAs } from 'file-saver';
getJobOutput() {
this.workflowService.fetchOutput(this.jobId,this.outputId).subscribe((response : any) => { // download file
var blob = new Blob([response.blob()], {type: 'application/octet-stream'});
var filename = 'file.csv';
saveAs(blob, filename);
});
}
Service is as below -
fetchOutput(jobId : string, outputId) {
var jobOutputURL = "myEnpoint";
var params = this.createHttpAuthorization(jobOutputURL,"GET");
params["format"] = "csv";
const options = {
headers: new HttpHeaders( { 'Content-Type': 'application/octet-stream',
'Accept' : 'application/octet-stream',
'Access-Control-Allow-Origin' : '*'}
)};
var endpoint = `${jobOutputURL}?oauth_consumer_key=${params["oauth_consumer_key"]}&oauth_signature_method=${params["oauth_signature_method"]}&oauth_nonce=${params["oauth_nonce"]}&oauth_timestamp=${params["oauth_timestamp"]}&oauth_version=1.0&format=${params["format"]}&oauth_signature=${params["oauth_signature"]}`;
return this.httpClient.get(endpoint, {...options, responseType: 'blob'});
}
To fetch an application/octet-stream, you have to set arraybuffer as the response type in the Angular HttpHeaders.
This is the service method:
fetchOutput(): Observable<ArrayBuffer> {
let headers = new HttpHeaders();
const options: {
headers?: HttpHeaders;
observe?: 'body';
params?: HttpParams;
reportProgress?: boolean;
responseType: 'arraybuffer';
withCredentials?: boolean;
} = {
responseType: 'arraybuffer'
};
return this.httpClient
.get('https://your-service-url.com/api/v1/your-resource', options)
.pipe(
map((file: ArrayBuffer) => {
return file;
})
);
}
This is the call to the service method and to the saveAs function:
this.yourService
.fetchOutput()
.subscribe((data: any) => {
const blob = new Blob([data], { type: 'application/octet-stream' });
const fileName = 'Your File Name.csv';
saveAs(blob, fileName);
})
As other users are suggestion: 401 Unauthorized is usually a client side error due to missing credentials.

Angular2 Http post 400

I have this service:
#Injectable()
export class HttpserviceService {
baseUrl: string = "http://localhost:3000/";
headers = new Headers({
'accept': 'application/json'
});
post(url: string, data: any): Observable<any> {
//send post request
return this.http.post(this.baseUrl+url, JSON.stringify(data))
.map(this.extractData) //this works
.catch(this.handleError); //this as well
}
}
and when I subscribe to that method:
user: User = {
username: "test",
password: "12345"
}
authUrl: string = 'user/auth';
return this.http.post(this.authUrl, user)
.subscribe(data => {
//console.log(data);
});
I'm getting an
Status Code:400 Bad Request
What can be wrong?
When I request using postman everything works ok
In postman i see that you have 1 header. Which you are not sending in angular
Try following, headers should go as a third parameter
post(url: string, data: any): Observable<any> {
//send post request
return this.http.post(this.baseUrl+url, JSON.stringify(data), {headers: this.headers})
.map(this.extractData) //this works
.catch(this.handleError); //this as well
}

post data in angular2

I am facing the issue of json added being added to the url after calling the service to add the data.
below is my file
first.ts
CreateNew(): void {
this.router.navigate(['/detail', 0]);
}
detail.ts
Submit() {
let templateId;
this.route.params.subscribe(
(param: any) => {
templateId = +param['templateid']; });
if (templateId === 0) {
this.jobservice.addJob(this.job).subscribe(error => this.errorMessage = <any>error);
}
this.router.navigate(['/template']);
}
service.ts
addJob(job: Job): Observable <Job> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
console.log(job);
return this.http.post('http://sample/api/Product/AddProduct', JSON.stringify(job), options).map(this.extractData).catch(this.handleError);
}
I am not able to find the issue why it is adding the json data to the url.
When you use the RequestOption, you dont use the method post, get, put or delete. But you use "request". Here is a sample request that works:
post<RQ, RS>(url: string, request: RQ, responseType: RS, withToken: boolean): Promise<RS> {
let postReq: Request = this.createAuthorizationHeader<RQ>(url, request, RequestMethod.Post, withToken);
return this.http.request(postReq).toPromise()
.then(res => {
return this.processingData<RS>(res, responseType);
})
.catch(this.handleError);
}
Then here you add your header to the request:
/**
* This function updates the token in the header
*/
createAuthorizationHeader<RQ>(url: string, requestData: RQ, method: RequestMethod, withToken: boolean) {
let headers = new Headers();
let options = new RequestOptions({
method: method,
url: url
});
/**
* Include token when boolean is passed
*/
if (withToken) {
headers.append('token', token);
options.headers = headers;
}
/**
* create bosy for post and put
*/
if (method === RequestMethod.Post || method === RequestMethod.Put) {
// do something
}
let request = new Request(options);
return request;
}
This should work, remember to use "http.request.." when you use request options
import { Http, Request, Response, Headers, RequestMethod, RequestOptions } from '#angular/http';
...
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({
method: RequestMethod.Post,
url: url,
headers = headers,
body: job
});
let request = new Request(options);
console.log(options);
return this.http.request(options).map(this.extractData).catch(this.handleError);
The issue was that while refresh of page it was showing 404 error.
In app.module.ts
Add imports: import { HashLocationStrategy, LocationStrategy } from '#angular/common';
And in NgMoudle provider, add: {provide: LocationStrategy, useClass: HashLocationStrategy}
which fixed the issue.
This should be working out fine. I have this working on my environment using angular 2.1.0.
import { Http, Request, Response, Headers, RequestMethod, RequestOptions } from '#angular/http';
...
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({
method: RequestMethod.Post,
url: 'localhost:51293/template',
headers = headers,
body: job
});
let request = new Request(options);
console.log(options);
return this.http.request(options).map(this.extractData).catch(this.handleError);

Add Header to the API Http request, Angular 2, Ionic 2

I have an ionic 2 app (which uses Angular 2 Http), i have the code which gets the JSON from the API, however i need to send the app-id, app-key and Accept as a header, this is the main code...
import {Component} from '#angular/core';
import {NavController} from 'ionic-angular';
import {Http} from 'angular2/http';
#Component({
templateUrl: 'build/pages/latest-page/latest-page.html'
})
export class LatestPage {
static get parameters() {
return [[NavController]];
}
constructor(_navController, http) {
this._navControler = _navController;
this.http = http;
this.http.get("https://twit.tv/api/v1.0/people/77").subscribe(data => {
console.log("Got Data");
this.items = JSON.parse(data._body).people;
}, error => {
console.log("Error with Data");
});
}
And this is how i tried to add the header, however its not working...
constructor(_navController, http) {
this._navControler = _navController;
this.http = http;
var headers = new Headers();
headers.append('app-id', '0000');
headers.append('app-key', 'abc000abc');
headers.append('Accept', 'application/json ');
this.http.get("https://twit.tv/api/v1.0/people/77"),{"Headers": headers}.subscribe (data => {
console.log("Got Data");
this.items = JSON.parse(data._body).people;
}, error => {
console.log("Error with Data");
});
}
Any ideas?
Thanks
Headers must be set inside the RequestOptions, which is the second parameter http.get()
Besides you have a syntax error in your code. Request options is the second parameter of .get(url, {}), and you wrote like this: .get(url),{}
this.http.get("https://twit.tv/api/v1.0/people/77",{"Headers": headers}).subscribe (data => {
console.log("Got Data");
this.items = JSON.parse(data._body).people;
}, error => {
console.log("Error with Data");
});
Creating explicitly request options.
let opt: RequestOptions
let myHeaders: Headers = new Headers
myHeaders.set('Content-type', 'application/json')
opt = new RequestOptions({
headers: myHeaders
})
_http.get(url, opt).
After some misunderstanding, I'll leave here you're own code with my suggestions:
constructor(_navController, http) {
/*this isn't necessary, _navController and http are already available for "this. "*/
this._navControler = _navController;
this.http = http;
let opt: RequestOptions
let myHeaders: Headers = new Headers
myHeaders.set('app-id', 'c2549df0');
myHeaders.append('app-key', 'a2d31ce2ecb3c46739b7b0ebb1b45a8b');
myHeaders.append('Content-type', 'application/json')
opt = new RequestOptions({
headers: myHeaders
})
this.http.get("https://twit.tv/api/v1.0/people/77",opt).subscribe (data => {
console.log("Got Data");
this.items = JSON.parse(data._body).people;
}, error => {
console.log("Error with Data");
});
}