I am taking the field of a form and passing it to a service as this.form.value when I am logging this.form.value on the console I am getting Object { email: "zxzx", password: "zxzxx" } when I am sending the same thing to the service and calling the server like :
import {Http} from 'angular2/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import {Injectable} from 'angular2/core'
import {Post} from './post';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class PostService {
//dependency injection
private _url = "http://127.0.0.1/accounts/login_user/";
constructor(private _http:Http) {
}
createPost(post){
return this._http.post(this._url,JSON.stringify(post))
.map(res=>res.json());
}
}
The server is being called but the values are not being passed. When I am logging the response on the console I am getting :
Object { _isScalar: false, source: Object, operator: Object }
Can somebody please help me solve this issue?
Thank you.
Your console.log prints the observable corresponding to your request but not its result. If you want to print this result, you can use the do operator:
createPost(post){
return this._http.post(this._url,JSON.stringify(post))
.map(res=>res.json())
.do(data => {
console.log(data);
});
}
You said that the request is executed. It's actually the case if you subscribe on the observable:
this.service.createPost(...).subscribe(() => {
(...)
});
Edit
You also need to set the Content-Type header:
createPost(post){
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post(this._url,JSON.stringify(post), { headers })
.map(res=>res.json())
.do(data => {
console.log(data);
});
}
Edit2
If you want to send an url-encoded form:
You also need to set the Content-Type header:
createPost(post){
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let content = new URLSearchParams();
content.set('prop', post.prop);
(...)
return this._http.post(this._url, content.toString(), { headers })
.map(res=>res.json())
.do(data => {
console.log(data);
});
}
You need to subscribe() otherwise the observable won't do anything:
createPost(post){
return this._http.post(this._url,JSON.stringify(post))
.map(res=>res.json())
.do(val => console.log(val));
}
...
this.createPost(...).subscribe(data => console.log(data));
Related
I'm using plain javascript to fetch data from php scripts server-side but I'd like to try it out using angular.
This code fetches a php file that in turn queries a database (simple select with filter, etc) and returns a json file to be used by the script and then displayed.
Is there a simple way of doing this with angular?
This is the script as it is now
fetch('service/select.php')
.then(function(response) {
return response.json();
})
.then(function(data) {
//do something with the data
});
and this is the php file it fetches:
<?php
require_once("config.php");
mysqli_set_charset($con, 'utf8mb4');
mysqli_query($con, "SET NAMES 'utf8mb4'");
$rs = mysqli_query($con, "select * from names");
while($row = mysqli_fetch_assoc($rs)) {
$res[] = $row;
}
echo json_encode($res, JSON_UNESCAPED_UNICODE);
?>
(I know the php file is vulnerable to sql injection, its just an example file to quickly query data, not used in production)
Demo HTTPClient module is your need
import {Injectable} from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
#Injectable()
export class DataService{
constructor(private http:HttpClient){ }
Post(url:string,body:any): Observable<any>{
return this.http.post<any>(url, body, httpOptions).pipe( retry(1), catchError(this.handleError) );
}
Get(url:string): Observable<any>{
return this.http .get<any>(url, httpOptions).pipe( retry(1), catchError(this.handleError) );
}
private handleError(error: any){
let body = error.json();
return body || {};
}
}
Angular provides HttpClient API to do HTTP requests. The response type of this API is Observable type of RxJS which has lots of built-in methods to
process your data.
You can do your HTTP request code as following in the angular way instead of fetch API.
const url = 'service/select.php';
const hdrs = new HttpHeaders({ 'Accept': accept ? accept : 'application/json; charset=utf-8' });
this.http.get(url, { headers: hdrs, observe: 'body', responseType: 'json'})
.subscribe(
data => // do whatever you want to do your data
err => // get the error response here
);
I have a json that is not being update on the first time I click on the button that updates it. The button in question calls this function:
recusaProposta(){
this.propostaService.atualizaDisputa(this.disputa)
.subscribe(
res => this.disputa.propostas_realizadas++,
error => console.log(error)
);
}
Now, at the first time I click on it nothing happens on the json but if I click on it again it does update the field I want (disputa.propostas_realizadas)
Here's the service:
import {Injectable} from '#angular/core';
import {Http, Headers, Response, RequestOptions} from '#angular/http';
import {Component} from '#angular/core';
import {Observable} from 'rxjs/Rx';
import {DisputaPropostaComponent} from './disputas-proposta.component';
import 'rxjs/add/operator/map';
#Injectable()
export class DisputaPropostaService{
contato:Object[] = [];
name: string;
headers:Headers;
url: string = 'http://localhost:3004/disputa';
constructor(private http: Http){}
atualizaDisputa (body:any): Observable<DisputaPropostaComponent[]>{
let bodyString = JSON.stringify(body); // Stringify payload
let headers = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON
let options = new RequestOptions({ headers: headers }); // Create a request option
return this.http.put(`${this.url}/${body['id']}`, body, options) // ...using post request
.map((res:Response) => res.json()) // ...and calling .json() on the response to return data
.catch((error:any) => Observable.throw(error.json().error || 'Ocorreu um erro em nosso servidor, tente novamente mais tarde')); //...errors if any
}
}
Can you guys help me? Thanks in advance.
The reason is that in your function you return disputa.propostas_realizadas before increasing it by 1. Replace your function with the code below and it should work.
recusaProposta(){
this.propostaService.atualizaDisputa(this.disputa)
.subscribe(
res => ++this.disputa.propostas_realizadas,
error => console.log(error)
);
}
In my Angular 2 application, I'm trying to use Http (#angular/http) to make requests to my API. For these requests to work, I need certain headers to be added to every request I make to the API (including a JWT header).
What I'd like to do is have an API class that takes care of creating the Http requests and some error handling and validation etc.
As it turns out, however, I cannot use the Http class from my API class, as it will come up with the following error;
user.service.ts
import { Injectable } from '#angular/core';
import {User} from "../models/User";
import {API} from "../API";
import {Http} from "#angular/http";
#Injectable()
export class UserService
{
constructor (private http : Http) {}
getProfile (user : User)
{
let api = new API (this.http);
return api.doRequest ('/user/' + user.id + '/profile');
}
}
API.ts
import {Http, Headers, RequestOptions} from '#angular/http';
export class API
{
...
constructor (private http : Http) {}
doRequest (url : string, method : string, data?)
{
let headers = {...};
let options = new RequestOptions ({ headers: new Headers (headers), ... } );
return this.http.get (url, data, options)
.catch ((error) => { ... } );
}
}
Things work better when using Http straight from the UserService, however.
Is there a way to fix this, or perhaps a better way to achieve the desired result? Should I just extend Http?
You should be using append() method to add headers and then pass it to request object as below
doRequest (url : string, method : string, data?)
{
headers= new Headers();
headers.append(name1,value1);
headers.append(name2,value2);
....
let options = new RequestOptions ({ headers: headers, ... } );
return this.http.get (url, data, options)
.catch ((error) => { ... } );
}
That's the way today setting HTTP headers (Angular > 4):
Import:
import {HttpClient, HttpHeaders} from '#angular/common/http';
and usage:
const headers = new HttpHeaders()
.set("X-CustomHeader", "custom header value");
Notice that we are building the headers object by chaining successive set() methods. This is because HttpHeaders is immutable, and its API methods do not cause object mutation.
Instead, a call to set will return a new HttpHeaders object containing the new value properties. So this means that the following will NOT work:
const headers = new HttpHeaders ();
headers.set("X-CustomHeader", "custom header value")
I was reading angular2 code and I found some confusing syntax for me.
The full code is below.(from https://github.com/domfarolino/angular2-login-seed)
import { Injectable, Inject } from '#angular/core';
//import { Control } from '#angular/common';
import { Http, Response, Headers, RequestOptions, RequestOptionsArgs } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
/**
* Import interfaces that service depends on
*/
import { User } from './user';
#Injectable()
export class UserService {
constructor (private http: Http, #Inject('apiBase') private _apiBase: string) {
}
private _loginApi = this._apiBase + '/authorize/local';
private _logoutApi = this._apiBase + '/logout';
private _authenticatedApi = this._apiBase + '/api/authenticated';
private _registerApi = this._apiBase + '/api/users/register';
private _userExistsApi = this._apiBase + '/api/users/exists';
login(user) {
let body = JSON.stringify(user);
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(this._loginApi, body, <RequestOptionsArgs> {headers: headers, withCredentials: true})
.map((res: Response) => res)
.catch(this.handleError);
}
authenticated() {
return this.http.get(this._authenticatedApi, <RequestOptionsArgs> {withCredentials: true})
.map((res: Response) => res.json())
.catch(this.handleError);
}
logout() {
return this.http.get(this._logoutApi, <RequestOptionsArgs> {withCredentials: true})
.map((res: Response) => res.json())
.catch(this.handleError);
}
register(user) {
let body = JSON.stringify(user);
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(this._registerApi, body, <RequestOptionsArgs> {headers: headers, withCredentials: true})
.map((res: Response) => res)
.catch(this.handleError);
}
getUsers() {
return this.http.get(this._apiBase + "/api/users?limit=5&desc=true", <RequestOptionsArgs> {withCredentials: true})
.map((res: Response) => res.json())
.catch(this.handleError);
}
getMe() {
return this.http.get(this._apiBase + '/api/users/me/', <RequestOptionsArgs> {withCredentials: true})
.map((res: Response) => res.json().me)
.catch(this.handleError);
}
private handleError (error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
return Observable.throw(error || "Server Error");
}
}
and I can't find out what below code as a parameter means.
<RequestOptionsArgs> {headers: headers, withCredentials: true}
Is there anyone can give me an idea?
The syntax <Type> variable is a cast. See Type Assertions on the documentation
Sometimes you’ll end up in a situation where you’ll know more about a value than TypeScript does. Usually this will happen when you know the type of some entity could be more specific than its current type.
Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler. TypeScript assumes that you, the programmer, have performed any special checks that you need.
It shows two examples, it is possible to cast using:
<string> somevar
and also with
somevar as string
The two samples are equivalent. Using one over the other is mostly a choice of preference; however, when using TypeScript with JSX, only as-style assertions are allowed.
class is work as a datatype here . ..
Ex .
Class student {
Name : String ,
RollNo: Number
}
now if i declare a variable
Public Students:Obect
Now i can push in students with a object having name and roll no.
Can anyone help what I am doing incorrect, anything missing?
I am getting undefined for --'this.ack.length'
this._activeChannelService.requestChannelChange(this.selectedchannel.channelName)
.subscribe(
ack => {
this.ack= ack;
console.log(" test: ", this.ack.length);
},
err => {
console.log(err);
});enter code here
ack is of time
ack:Iack[];
Iack has two field of type string. result and message
I need to iterate through array of Iack[] to get the result and message
if message=success then call the another service
service
requestChannelChange (name: string): Observable<Iack[]> {
alert('in servicerequestChannelChange');
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
let postchannelname = "channelName=" + name;
let requestt = new IRequest(name);
console.log(JSON.stringify(requestt));
return this._http.post(this._activateChangeUrl, JSON.stringify(requestt),{ headers: headers })
//.map(this.extractData)
.map((res:Response) => res.json() as Iack[])
.do(data => console.log("All: " + JSON.stringify(data)))
.catch(this.handleError);
}
You can use observable in your TS service:
import { Injectable } from '#angular/core';
import { IPost } from './IPost';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
#Injectable()
export class PostServices {
private _webApiBaseUrl = "http://localhost:62806/v1/Posts"
private _http : Http;
constructor(http : Http){
this._http = http;
}
getAll(): Observable<IPost[]> {
return this._http.get(this._webApiBaseUrl + '/all', this.getHeaders())
.map((response: Response) => response.json())
.do(data => console.log(`All Data: \n ${ JSON.stringify(data) }`))
.catch(this.handleError);
}
private handleError(error: Response){
console.error(error);
return Observable.throw(error.json().error || 'Server Error');
}
private getHeaders()
{
let headers = new Headers();
headers.append("Authorization", "");
headers.append("Content-Type", "application/json");
return new RequestOptions({ headers: headers });
}
}
Usage in your TS class:
import { Component, OnInit } from '#angular/core';
import { IPost } from './IPost';
import { PostServices } from './posts.service';
#Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.css']
})
export class PostsComponent implements OnInit {
posts: IPost[];
errorMessage: string;
private _postService: PostServices;
constructor(postService: PostServices) {
this._postService = postService;
}
ngOnInit() {
this._postService.getAll()
.subscribe(
data => {this.posts = data; console.log("data.length: " + data.length)}, // here
error => this.errorMessage = <any>error
);
}
}
enter code here is executed before this.ack= ack; is executed
This is a function
ack => {
this.ack= ack;
console.log(" test: ", this.ack.length);
}
that you pass to subscribe(...) and the observable calls it when the data arrives which can take a looong time when it's a call to a server.
enter code here is executed immediately.
You'll have to check for success within the service subscription. An observable is an asynchronous call, so any calls you want to make regarding the data in that async call must be made within it to remain a safe call.
So, make your seconds service call, within the subscription.