Ok I'm really confused about this one. I have a angular2 app and it successfully does a http GET request to my localhost server. I implement a return type of IHttpActionResult with a return status of Ok and send some content back but when I look at the response on my console the content is blank but ti is retrieving the appropriate status code ie(200 ok). I need to find a way to send back json to my andular2 service.
Below is my WebAPI2 controller:
[Route("api/login")]
public class LoginController : ApiController
{
[HttpGet]
public IHttpActionResult Login()
{
//return Content(HttpStatusCode.OK, Json(new { success = true }));
//return Json(new { success = true });
List<int> myValues = new List<int>(new int[] { 1, 2, 3 });
return Ok(myValues);
}
}
My angular2 Service:
import { Injectable } from '#angular/core';
import { Http, Headers, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
#Injectable()
export class AuthService {
isLoggedIn = false;
private _url = "http://localhost:61333/";
constructor(private _http: Http) { }
login(login) {
return this._http.get(this._url + "api/login").map(res => res.json());
}
logout() {
this.isLoggedIn = false;
}
}
And my angular2 component that is invoking my login function in my service
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FormGroup } from '#angular/forms';
// Services
import { AuthService } from '../../_services/auth.service';
// Models
import { Login } from '../../_models/login.class';
#Component({
styles: [require('./login.component.css')],
template: require('./login.component.html')
//providers: [AuthService]
})
export class LoginComponent implements OnInit {
loginObj = new Login();
constructor(private _authService: AuthService, private _router: Router) {
}
login(form) {
this.loginObj.email = form.form._value.email;
this.loginObj.password = form.form._value.password;
this._authService.login(this.loginObj).subscribe(
value => { console.log("SUC:" + value); }
);
}
}
Thanks you.
Ross
Related
I develop a web API using .NET Core web API and then try to get data from it to my Angular11.
these are the codes
shared.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { observable, Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class SharedService {
readonly APIUrl = "http://localhost:5000/api";
readonly PhotoUrl = "http://localhost:5000/photos";
constructor(private http: HttpClient) { }
getSecList(): Observable<any[]> {
return this.http.get<any>(this.APIUrl + '/section');
}}
show-sec.component.ts
import { Component, OnInit } from '#angular/core';
import { SharedService } from './../../shared.service';
#Component({
selector: 'app-show-sec',
templateUrl: './show-sec.component.html',
styleUrls: ['./show-sec.component.css']
})
export class ShowSecComponent implements OnInit {
constructor(private service: SharedService) { }
SectionList: any = [];
ngOnInit(): void {
this.refreshSecList();
}
refreshSecList() {
this.service.getSecList().subscribe(data => {
this.SectionList = data;
console.log(this.SectionList);
});
}
}
but I can not get data from api it shows following error in console.
how to fix this.
I am calling a WCF service from my angular 6 code and the data that is returned is in JSON. But when I am accepting the returned data it is throwing some error like :
Cannot find a differ supporting object '[{"Company_Prefix":"SCL","Company_Name":"Smart Chip Private Limited","Company_Code":"SCL"},{"Company_Prefix":"SYS","Company_Name":"Syscom Corporation Private Limited","Company_Code":"SYS"},{"Company_Prefix":"V-SCL","Company_Name":"Vihaan Infrasystems India Limited","Company_Code":"V-SCL"},{"Company_Prefix":"OT","Company_Name":"OT Morpho","Company_Code":"OT"}]' of type 'string'. NgFor only supports binding to Iterables such as Arrays.
I have tried MAP and It doesn't help.
TS file:
import { CompanyModel } from './../Models/app.CompanyModel';
import { CommonService } from './../../Shared/Common.service';
import { Component, OnInit } from '#angular/core';
import { CreateEmployeeModel } from '../Models/app.create-EmployeeModel';
#Component({
selector: 'app-create-employee',
templateUrl: './create-employee.component.html',
styleUrls: ['./create-employee.component.css',
'../../Content/vendor/bootstrap/css/bootstrap.min.css']
})
export class CreateEmployeeComponent implements OnInit {
private _employeeModel : CreateEmployeeModel;
UserName:string = sessionStorage.getItem('UserName');
companies: CompanyModel[];
departments: string[];
errorMessage: any;
constructor(private _CommonService:CommonService) { }
ngOnInit(): void {
debugger;
this._employeeModel = new CreateEmployeeModel();
this._employeeModel.UserName=this.UserName;
this._CommonService.BindCompany(this._employeeModel)
.subscribe(data =>
{
debugger;
this.companies=data;
},
error => this.errorMessage = <any>error);
// this._CommonService.BindDepartment(this._employeeModel).subscribe(data=>this.departments=data);
}
**Service:**
import { CompanyModel } from './../HR/Models/app.CompanyModel';
import { CreateEmployeeModel } from './../HR/Models/app.create-EmployeeModel';
import { Injectable } from '#angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators';
import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpErrorResponse, HttpHeaders } from '#angular/common/http';
import { Router } from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class CommonService {
private _parse;
private _response;
private data: any;
constructor(private _http: HttpClient, private _Route: Router) { }
private api='http://localhost:10704/CommonService.svc';
BindCompany(EmployeeModel: CreateEmployeeModel): Observable<CompanyModel[]>
{
let headers = new HttpHeaders({ 'Content-Type': 'application/json' });
debugger;
return this._http.get<CompanyModel[]>( this.api+'/BindCompany/' + EmployeeModel.UserName, { headers: headers } )
.pipe(tap(data=>{
debugger;
// this._parse=JSON.parse(data);
console.log(data);
if(data!=null)
{
return (data);
}
else
{
return null;
}
}),
catchError(this.handleError)
);
}
`````````````````````````````````````````````````````````````````````````
**JSON DATA THAT API RETURNS:**
`````````````````````````````````````````````````````````````````````````
[{"Company_Prefix":"XXX",
"Company_Name":"XXX Private Limited",
"Company_Code":"XXX"},
{"Company_Prefix":"XXX",
"Company_Name":"XXX Corporation Private Limited",
"Company_Code":"XXX"},
{"Company_Prefix":"V-XXX",
"Company_Name":"XXX Infrasystems India Limited",
"Company_Code":"V-XXX"},
{"Company_Prefix":"XXX",
"Company_Name":"OT XXX",
"Company_Code":"XXX"}]
It seems that you're not parsing the response. Make amend to your service while referring to the code below.
return this._http.get<CompanyModel[]>( this.api+'/BindCompany/' + EmployeeModel.UserName, { headers: headers } )
.pipe(tap(data=>{
if(data!=null)
{
return JSON.parse(data);
}
else
{
return null;
}
}),
catchError(this.handleError)
);
I am working with angular 6 trying to send a post request using httpclient , but always receive null body on the server side.
save( rules:RuleModel[]){
let _headers: HttpHeaders = new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8'
});
return this._httpClient.post(AppConfig.BaseUrl,JSON.stringify(rules), {headers:_headers} ); }
and API function
[HttpPost]
public List<Rule> AddTemplateTextRules( [FromBody]Rule[] Rules)
{
try
{
return RuleManager.AddRule(Rules);
}
catch (Exception e)
{
return null;
}
return null;
}
To make a post request in Angular 6 with standard practice you need to do followings:
In the service class:
import {throwError, Observable } from 'rxjs';
import {catchError} from 'rxjs/operators';
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams, HttpErrorResponse } from '#angular/common/http';
import { Rule } from 'path';
#Injectable()
export class RuleService {
constructor(private httpClient: HttpClient) { }
private baseUrl = window.location.origin + '/api/Rule/';
createTemplateTextRules(rules: Rules[]): Observable<boolean> {
const body = JSON.stringify(rules);
const headerOptions = new HttpHeaders({ 'Content-Type': 'application/json' });
return this.httpClient.post<boolean>(this.baseUrl + 'AddTemplateTextRules', body, {
headers: headerOptions
}).pipe(catchError(this.handleError.bind(this));
}
handleError(errorResponse: HttpErrorResponse) {
if (errorResponse.error instanceof ErrorEvent) {
console.error('Client Side Error :', errorResponse.error.message);
} else {
console.error('Server Side Error :', errorResponse);
}
// return an observable with a meaningful error message to the end user
return throwError('There is a problem with the service.We are notified &
working on it.Please try again later.');
}
}
In the Component:
export class RuleComponent implements OnInit {
constructor(private ruleService: RuleService) { }
createTemplateTextRules(): void {
this.ruleService.createTemplateTextRules(rules).subscribe((creationStatus) => {
// Do necessary staff with creation status
}, (error) => {
// Handle the error here
});
}
}
Then in the ASP.NET Core API Controller:
[Produces("application/json")]
[Route("api/Rule/[action]")]
public class RuleController : Controller
{
[HttpPost]
public Task<IActionResult> AddTemplateTextRules( [FromBody]Rule[] Rules)
{
try
{
return RuleManager.AddRule(Rules);
}
catch (Exception e)
{
return false;
}
return Json(true);
}
}
Hope it will help you.
With the latest RxJS(Angular 14) here is the way:
Service
Login(phone:string,password:string)
{
let _headers: HttpHeaders = new HttpHeaders({
'accept': 'application/json'
});
return this.http.post(this.url,{username,password},{headers:_headers})
.pipe(map(response=>response));
}
Component
async Login(phone:string,password:string)
{
let token$ = this.authService.Login(phone,password);
let token = await lastValueFrom(token$);
}
Since I was returning just text and not Json from the API, this was my code to handle text response type in the Service. If you're getting a response parse error, explicitly defining the responseType will help since Json is default.
Login(phone:string,password:string)
{
let _headers: HttpHeaders = new HttpHeaders({
'accept': 'text/plain'
});
return this.http.post(this.url+'security/login?phone='+phone+'&password='+password,null,{headers:_headers,responseType:'text'})
.pipe(map(response=>response));
}
I have an ASP.NET MVC app and I'm struggling with the connection between the typescript and the C#.
I can see that the C# is giving the response in the Inspect, the value is there but I don't know how to treat in Typescript.
C# Code:
namespace TEST.Controllers
{
[Route("api/[controller]")]
public class TestController : Controller
{
// GET api/GetTest
[HttpGet("GetTest")]
public IEnumerable<string> GetTest()
{
return new string[] { "Teste1", "Teste2" };
}
}
}
TypeScript SERVICE Code:
public getTest(): Observable<any> {
return this.dataService.get(this.baseUrl + '/GetTest')
.map((response: Response) => <any>response.json())
// .do(data => console.log("All: " + JSON.stringify(data)))
.catch(this.handleError);
}
Data Service Code (TypeScript):
public get<T>(url: string, params?: any): Observable<T> {
const options = new DataServiceOptions();
options.method = RequestMethod.Get;
options.url = url;
options.params = params;
return this.request(options);
}
private request(options: DataServiceOptions): Observable<any> {
options.method = (options.method || RequestMethod.Get);
options.url = (options.url || '');
options.headers = (options.headers || {});
options.params = (options.params || {});
options.data = (options.data || {});
this.interpolateUrl(options);
this.addXsrfToken(options);
this.addContentType(options);
this.addAuthToken(options);
// this.addCors(options);
const requestOptions = new RequestOptions();
requestOptions.method = options.method;
requestOptions.url = options.url;
requestOptions.headers = options.headers;
requestOptions.search = this.buildUrlSearchParams(options.params);
requestOptions.body = JSON.stringify(options.data);
this.pendingCommandsSubject.next(++this.pendingCommandCount);
const stream = this.http.request(options.url, requestOptions)
.catch((error: any) => {
this.handleErrors(error);
return Observable.throw(error);
})
.map(this.unwrapHttpValue)
.catch((error: any) => {
return Observable.throw(this.unwrapHttpError(error));
})
.finally(() => {
this.pendingCommandsSubject.next(--this.pendingCommandCount);
});
return stream;
}
The Calling:
private getDataBase() {
this.service.getTest().subscribe((res) => {
console.log(res);
this._proceduresImportData = res;
});
}
OBS: I also can console the observable, but I cannot treat it.
The best way to approach this is to have a generic request service and encapsulate your service calls, then inject that in where you need it. Taking get for an example (this can be expanded upon)
request.service.ts
import { Injectable } from "#angular/core";
import { Http, Response } from "#angular/http";
import { Observable } from "rxjs/Observable";
import "rxjs/add/operator/map";
import { WindowRef } from "./window.service";
#Injectable()
export class RequestService {
private baseUrl: string;
constructor(private http: Http, private windowRef: WindowRef) {
this.baseUrl = this.getBaseUrl();
}
public get<T>(resource: string): Observable<T> {
return this.http.get(this.baseUrl + resource)
.map<Response, T>(this.extractData);
}
private extractData(response: Response) {
return response.json();
}
private getBaseUrl(): string {
if (this.windowRef.getNativeWindow().location.hostname === "localhost") {
return "http://localhostAddress/api/";
} else if (this.windowRef.getNativeWindow().location.hostname === "anotherEnviroment") {
return "https://anotherAddress/api/";
}
}
}
window.service.ts
import { Injectable } from "#angular/core";
#Injectable()
export class WindowRef {
public getNativeWindow(): any {
return window;
}
}
This then returns an observable of the object you are expecting, used with a resolver or onInit it can be subscribed to where needed.
get-stuff.service.ts
import { Injectable } from "#angular/core";
import { Observable } from "rxjs/Observable";
import { RequestService } from "../common/request.service";
#Injectable()
export class Service {
constructor(private requestService: RequestService) { }
public getTestService(): void {
let requestedStuff: Observable<string[]> = this.requestService.get<string[]>(`GetTest`);
requestedStuff.subscribe(stuff: string[]) => {
//do stuff with your string
}
}
}
Then subscribe and use your data
Hope that helps
I am trying to load data from my web api controller.
Currently I am using my API service which I call from the ngOnInit function of the component.
But, nothing return in the view because it's an asynchronous data
Web api controller
[HttpGet("[action]")]
public async Task<UserModel> GetUserById(int id)
{
Response.StatusCode = 200;
try
{
_context = new AuthentificationDbContext();
UserModel user = await _context.User.SingleOrDefaultAsync(m => m.id == id);
if (user == null)
{
return null;
}
else
return (user);
}
catch (SqlException ex)
{
throw ex;
}
}
userService.ts
getUserId(id: number) : Observable<User>{
return this.http.get(this.url + 'userApi/GetUserById/?id=' + id)
.map(res => <User>res.json())
.catch(this.handleError);
}
app.routing.ts
{ path: 'user/:id', component: UserComponent}
export const routing = RouterModule.forRoot(appRoutes,{
enableTracing:true});
export const routedComponents = [UserComponent];
user.component.ts
export class UserComponent implements OnInit {
private user: User;
constructor(private userService: UserService, private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.route.paramMap
.switchMap((params: ParamMap) =>
this.userService.getUserId(+params.get('id')))
.subscribe((user: User) => {
this.user = user;
});
}
}
user.cshtml
<div *ngIf="user">{{ user.name}}</div>
But, when I tried with that example, that's work because not asynchronous
import { Injectable, Inject } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
export class User {
constructor(public id: number, public name: string) { }
}
let Users = [
new User(11, 'Mr. Nice'),
new User(12, 'Narco')
];
let usersPromise = Promise.resolve(Users);
#Injectable()
export class UserService {
constructor( #Inject(Http) public http: Http) { }
getUserId(id: number | string) {
return usersPromise
.then(users => users.find(user => user.id === +id));
}
}
My question : how to load async data in ngOnInit?
I used by promise also, but doesn't work
If you use
{{user.view}}
in the components template, you'll get an error, because user isn't available immediately.
{{user?.view}}
(safe-nativation operator) avoids this error by not throwing an exception when user is null.
I can resolve my problem (it's related to routing) :
my code just need to insert this :
<script>document.write('<base href="' + document.location + '" />');</script>
at the top of the 'head' section.
And to insert in constructor from app.component.ts, this methode:
click() {
this.router.navigate(['', { foo: 'bar' }]);
}