I am quite new to angular2 and rxjs. I am trying to create an angular2 app that gets some data from jsonAPI,
i want to get data every 5 second,
i found a solution with Observable.interval(5000) but i have some error while compiling,
how to insert Observable.interval(500) in ngOnInit() code
please!!
import { Component, OnInit } from '#angular/core';
import { IProduct } from './product';
import { ProductService } from './product.service';
#Component({
templateUrl: 'app/products/product-list.component.html',
styleUrls: ['app/products/product-list.component.css']
})
export class ProductListComponent implements OnInit {
pageTitle: string = 'Product List';
imageWidth: number = 50;
imageMargin: number = 2;
showImage: boolean = false;
listFilter: string;
errorMessage: string;
products: IProduct[];
constructor(private _productService: ProductService) {
}
toggleImage(): void {
this.showImage = !this.showImage;
}
ngOnInit(): void {
this._productService.getProducts()
.subscribe(products => this.products = products,
error => this.errorMessage = <any>error);
}
onRatingClicked(message: string): void {
this.pageTitle = 'Product List: ' + message;
}
}
productservice.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import { IProduct } from './product';
#Injectable()
export class ProductService {
private _productUrl = 'api/products/products.json';
constructor(private _http: Http) { }
getProducts(): Observable<IProduct[]> {
return this._http.get(this._productUrl)
.map((response: Response) => <IProduct[]> response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
getProduct(id: number): Observable<IProduct> {
return this.getProducts()
.map((products: IProduct[]) => products.find(p => p.productId === id));
}
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
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
You need to modify inside your ProductService.ts as follows,
getProducts(){
Observable.interval(5000)
.flatMap(() => this.http.get(URL)
.map( res => res.json() )
.catch( (error:any) => Observable.throw(error.json().error || 'Server error') ) )
.subscribe(data => {
console.log(data)
})
}
make sure your service look like this and you don't miss any imports:
import 'rxjs/Rx';
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
#Injectable()
export class ProductService{
constructor(private _http:Http) {}
getData() {
return Observable.interval(5000).flatMap(() => {
return this._http.get(`URL GOES HERE`)
.map(res => res.json());
});
}
}
and in your component:
import { Component, OnInit } from '#angular/core';
import { ProductService } from './product.service';
export class ProductListComponent implements OnInit {
constructor(public _productService: ProductService) {}
ngOnInit() {
this._productService.getData()
.subscribe(data => this.products = data,
err => console.log(err));
}
}
This should work but make sure that you share any errors that you get in the console as your question is missing that.
Related
I kept getting the error in the title of this post. So I removed my .json() from response.json()
my below code return this.http.post('http://localhost:3000/sign-up', body, {headers: headers})
.map((response: Response) => response.json())
However, now I am getting as an error:
Response {_body: "<!DOCTYPE html>↵<html lang="en">↵<head>↵ <base …src="/js/app/bundle.js"></script>↵</body>↵</html>",
I am new to web development, and I'm trying to use code from an online course I took. I know my console.log should be an object and not this 'Response'. How do I get my returned data to be the information I submitted through an html form?
Also, I am leaving the .json() in my code posted below that way it shows what I originally had to get the Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) error. But like I said, I removed that .json() and got the Response {_body: "<!DOCTYPE html>↵<html lang="en">↵<head>↵ <base …src="/js/app/bundle.js"></script>↵</body>↵</html>", error
import { Injectable } from "#angular/core";
import { Http, Headers, Response } from "#angular/http";
import 'rxjs/Rx';
import { Observable } from "rxjs";
import { User } from "./user.model";
import { ErrorService } from "../errors/error.service";
#Injectable()
export class AuthService {
constructor(private http: Http, private errorService: ErrorService) {}
signup(user: User) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('http://localhost:3000/sign-up', body, {headers: headers})
.map((response: Response) => response.json());
// .catch((error: Response) => {
// this.errorService.handleError(error.json());
// return Observable.throw(error.json());
// });
}
}
Next Class
import { Component, OnInit } from "#angular/core";
import { FormGroup, FormControl, Validators } from "#angular/forms";
import { AuthService } from "./auth.service";
import { User } from "./user.model";
#Component({
selector: 'app-signup',
templateUrl: './signup.component.html'
})
export class SignupComponent implements OnInit {
myForm: FormGroup;
constructor(private authService: AuthService) {}
onSubmit() {
const user = new User(
this.myForm.value.email,
this.myForm.value.password,
this.myForm.value.firstName,
this.myForm.value.lastName,
this.myForm.value.age,
this.myForm.value.goal
);
this.authService.signup(user)
.subscribe(
data => console.log(data),
error => console.error(error)
);
this.myForm.reset();
}
ngOnInit() {
this.myForm = new FormGroup({
firstName: new FormControl(null, Validators.required),
lastName: new FormControl(null, Validators.required),
email: new FormControl(null, [
Validators.required,
Validators.pattern("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
]),
password: new FormControl(null, Validators.required),
age: new FormControl(null, Validators.required),
goal: new FormControl(null, Validators.required)
});
}
}
The problem is in the content you are getting back, you are receiving an HTML content while your code is expecting a json content. All you have to do is configure your server to return json instead, or fix your code to handle HTML response.
I have a json file and I'm trying to put this information in my project with a service in Angular 2. Here is my code:
That is my service:
import { Injectable } from '#angular/core';
import { Http, Response} from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class RecordsService {
data: any;
constructor(private http: Http) { }
getRecords(id) {
return this.http.get('../assets/data/03_data.json')
.map(data => {
this.data = data;
}, err => {
if (err) {
return err.json();
}
});
}
}
That is the component:
import { Component, OnInit } from '#angular/core';
import { RecordsService } from '../shared/services/records.service';
#Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.css'],
providers: [RecordsService]
})
export class ContentComponent implements OnInit {
constructor(private recService: RecordsService) { }
ngOnInit() {
}
getRecords(id) {
this.recService.getRecords(id)
.subscribe(data => {
console.log(data);
}, err => {
console.log(err);
});
}
}
Can someone help me what I did wrong. Thanks!
You are not calling getRecords() anywhere so it will not be fired at all. We found out that the id wasn't supposed to be a parameter in getRecords() at all. So call the method in OnInit:
ngOnInit() {
this.getRecords();
}
also you need to return the actual json from the response, i.e .json() so do:
.map(data => {
this.data = data.json();
return data.json();
}
You need to return something from your map statement:
.map(data => {
this.data = data;
return data;
}
I'm new to nativescript and angular 2 development. Currently, in the application that i'm building, HTTP post returns a JSON object like
[
{
"firstname": "test",
"isauth": true,
"lastname": "client",
"roleid": 10,
"rolename": "",
"userid": 3507,
"username": ""
}
]
I'm required to somehow save the userid (returned by Backendservice.apiUrl) value from the above response in login.component.ts and use that to pass to another API (Backendservice.requesturl ) that I'll be calling from another component(invoked clientmaster.component.ts). How do I do this on {N} + angular2.
Can I use applicationsettings setstring to persist the userid value and use it when I make the next call?If that's possible how do I parse the JSON response from the observable and save the userid value ?
I know that I can use flatmap to make chained http requests. But I'm not quite sure about how to do it and i'm very new to angular 2 development and RxJs observable concepts.
Here's my code:
login.service.ts
login(user: User) {
let headers = new Headers();
//In the headers object, the Content-Type specifies that the body represents JSON.
headers.append("Content-Type", "application/json");
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', user.username);
urlSearchParams.append('pwd', user.password);
let body = urlSearchParams.toString();
console.log("body"+body);
return this.http.post(
BackendService.apiUrl,
body,
{headers: headers })
.map((response ) => {
response.json();
// login successful if there's a jwt token in the response
console.log("RESPONSE: "+response.url);
console.log("response json "+response.status);
var body = response.json();
console.log("JSON BODY: ",JSON.stringify(body));
}
)
.catch(this.handleErrors);
}
getAssociatedRequest(){
let headers = new Headers();
//call made to the next URL
return this.http.get(
BackendService.requestUrl
)
.map((response: Response) => {
// login successful if there's a jwt token in the response
console.log("RESPONSE: ",response);
var body = response.json();
console.log("JSON BODY: ",JSON.stringify(body));
alert(JSON.stringify(body));}
)
.catch(this.handleErrors);
}
logoff() {
BackendService.token = "";
}
handleErrors(error: Response) {
console.log(JSON.stringify(error.json()));
return Observable.throw(error);
}
}
login.component.ts
import { Component, ElementRef, OnInit, ViewChild } from "#angular/core";
.....
.....
#Component({
selector: "vp-login",
moduleId: module.id,
providers: [LoginService],
templateUrl: "./login.component.html",
styleUrls: ["./login.component.css", "./login.css"],
})
export class LoginComponent implements OnInit {
user: User;
isAuthenticating = false;
constructor(private router: Router,
private loginService : LoginService,
private page: Page) {
this.user = new User();
}
ngOnInit() {
this.page.actionBarHidden = true;
}
login() {
if (getConnectionType() === connectionType.none) {
alert("Vessel-Pro requires an internet connection to log in.");
return;
}
try {
this.loginService.login(this.user)
.subscribe(
() => {
this.isAuthenticating = false;
this.router.navigate(["/clientMaster"]);
},
(error) => {
alert("Unfortunately we could not find your account.");
this.isAuthenticating = false;
}
);
} catch (error) {
console.log(error.message);
}
}
}
clientmaster.component.ts
import { Component, ElementRef, OnInit, ViewChild } from "#angular/core";
import { alert, LoginService, User } from "../shared";
...
#Component({
selector: "clientMaster",
moduleId: module.id,
templateUrl: './clientmaster.component.html',
styleUrls: ["./clientmaster.component.css"],
providers: [LoginService]
})
export class ClientMasterComponent implements OnInit{
isLoading = false;
constructor(private router: Router,
private LoginService: LoginService,
private page: Page) {}
ngOnInit(){
this.page.actionBarHidden = true;
}
/**
* gotoSRTPage
*/
public gotoSRTPage() {
this.router.navigate(["srtDetails"])
}
loadsrt(){
// alert("OK");
if (getConnectionType() === connectionType.none) {
alert("Oops!! looks like your device is not connected to the internet ");
return;
}
this.LoginService.getAssociatedRequest()
.subscribe(
(response) => {
console.log("Success Response" + response)
},
(error) => { console.log("Error happened", error.message)},
() => { console.log("srt is completed")
}
);
push.component.ts
import { Component, OnInit } from '#angular/core';
import {PushResult} from './dto/pushResult';
import {PushRequest} from './dto/pushRequest';
import {PushService} from './push.service';
#Component({
// selector: 'push-comp',
template:
// `<form (submit)="submitForm()">
// <input [(ngModel)]="element.name"/>
//
// <button type="submit">Submit the form</button>
// </form>
// <br>
`<button (click)="getHeroes()"> get </button> <button (click)="saveHeroes()"> push </button>`,
// templateUrl: 'app/html/heroes.component.html',
providers: [PushService]
})
export class PushComponent implements OnInit {
pushResult:PushResult;
// selectedHero:Hero;
// addingHero = false;
error:any;
element:any;
constructor(private pushService:PushService) {
console.info("in PushComponent constructor()");
}
getHeroes() {
this.pushService
.doSomeGet();
// .then(pushResult => this.pushResult = pushResult)
// .catch(error => this.error = error);
}
saveHeroes() {
var pushRequest: PushRequest = new PushRequest();
// this.pushService.doSelectMessagesAttributesUrl2(pushRequest);
this.pushService.doFeatureCreateNewMessageUrl(pushRequest);
this.pushService.doFeatureSelectPushMessages(this.element);
// .then(pushResult => this.pushResult = pushResult)
// .catch(error => this.error = error);
}
ngOnInit() {
console.info("in PushComponent ngOnInit()");
// this.getHeroes();
// this.saveHeroes();
}
}
push.service.ts
import { Injectable } from '#angular/core';
import {Http, Response, Headers} from '#angular/http';
import 'rxjs/add/operator/toPromise';
import 'rxjs/Rx';
import { PushResult } from './dto/pushResult';
import {PushRequest} from './dto/pushRequest';
import {StringUtilsService} from "../shared/stringUtils.service";
#Injectable()
export class PushService {
//private pushUrl = 'http://www.ynet.com'; // URL to web api
// private getUrl = '/app/eladb.json'; // URL to web api
private getUrl = '/SupporTool/ShowConfig?id=4'; // URL to web api
private selectMessagesAttributesUrl = '/SupporTool/Push/SelectMessagesAttributes'; // URL to web api
private postMultiMap = '/SupporTool/Push/FeatureCreateNewMessage'; // URL to web api
private postBoolean = '/SupporTool/Push/FeatureSelectPushMessages'; // URL to web api
private stringUtilsService : StringUtilsService;
constructor(private http: Http) {
this.stringUtilsService = new StringUtilsService();
}
doSomeGet() {
console.info("sending get request");
let headers = new Headers({
'Content-Type': 'application/xml'});
this.http.get(this.getUrl, {headers: headers})
.map(res => res.text())
.subscribe(
data => { console.info("next: "+data) },
err => console.error(err)
);
}
doSelectMessagesAttributesUrl2(pushRequest : PushRequest) {
console.info("sending post request");
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'});
return this.http
.post(this.selectMessagesAttributesUrl, "", {headers: headers})
.map(res => res.json())
.subscribe(
data => { console.info("next: "); console.info(data) },
err => console.error(err)
);
}
doFeatureCreateNewMessageUrl(pushRequest : PushRequest) {
console.info("sending post request");
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'});
var isLimit = true;
return this.http
.post(this.postBoolean, "#limit="+isLimit, {headers: headers})
.map(res => res.json())
.subscribe(
data => { console.info("next: "); console.info(data) },
err => console.error(err)
);
}
doFeatureSelectPushMessages(element : any) {
console.info("sending post request");
let dict = {"limit":"true", "name":"foo"}
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'});
var params = {};
params['push_input_internal_id'] = "1";
params['b'] = "2";
var formParamString = this.stringUtilsService.mapToFormParamsString(params);
return this.http
.post(this.postMultiMap, formParamString , {headers: headers})
.map(res => res.json())
.subscribe(
data => { console.info("next: "); console.info(data) },
err => console.error(err)
);
}
private handleError(error: any) {
console.error('An error occurred', error);
// return Promise.reject(error.message || error);
}
}
push.component.spec.ts
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { addProviders, async, inject } from '#angular/core/testing';
import { PushComponent } from './push.component';
describe('Component: Push', () => {
it('should create an instance', () => {
let component = new PushComponent();
expect(component).toBeTruthy();
});
});
app.routing.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { PushComponent } from './push/push.component';
const appRoutes: Routes = [
{ path: '', redirectTo: '/push', pathMatch: 'full' },
{ path: 'push', component: PushComponent}
];
export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
I read this post, but it used to work for me. So i cannt understand what i am missing.
and i get this error after npm start
Build error
The Broccoli Plugin: [BroccoliTypeScriptCompiler] failed with:
Error: Typescript found the following errors:
/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/tmp/broccoli_type_script_compiler-input_base_path-2GTEvnc7.tmp/0/src/app/push/push.component.spec.ts (10, 21): Supplied parameters do not match any signature of call target.
at BroccoliTypeScriptCompiler._doIncrementalBuild (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:120:19)
at BroccoliTypeScriptCompiler.build (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:43:10)
at /Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/node_modules/broccoli-caching-writer/index.js:152:21
at lib$rsvp$$internal$$tryCatch (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1019:11)
at lib$rsvp$asap$$flush (/Users/eladb/WorkspaceQa/SupporTool/src/main/webapp/html/ng2/node_modules/angular-cli/node_modules/rsvp/dist/rsvp.js:1198:9)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
PushComponent expects a PushService instance as parameter
constructor(private pushService:PushService) {
but you don't provide one
new PushComponent(/* parameter value missing */);
If you create an instance yourself with new Xxx() then Angulars DI is not involved and no dependencies are passed.
Only when Angulars DI itself creates PushComponent does it resolve and pass dependencies.
import {beforeEachProviders, it, describe, inject} from '#angular/core/testing';
describe('my code', () => {
beforeEachProviders(() => [PushService, PushComponent]);
it('does stuff', inject([PushComponent], (pushComponent) => {
// actual test
});
});
Don't expect to get a component injected. What you get this way is an instance of the components class (without any change detection running, nor lifecycle hooks being called, ...)
If you want a component, then you need to use TestBed. See also https://github.com/angular/angular/blob/master/CHANGELOG.md
Hitting this old issue in Angular 2 RC1.. Very frustrating stuff.. has anyone go any idea what I can do here to make this compile..
The line thats causing the error is :
this.project = res.project;
Here is my component:
import {Component} from '#angular/core';
import {ProjectsMainApi} from "../../../services/projects-main";
import { RouteConfig, RouteParams, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '#angular/router-deprecated';
declare var jQuery: any;
#Component({
selector: 'projects',
templateUrl: './app/components/Projects/details/project-single.html',
directives: [ROUTER_DIRECTIVES]
})
export class ProjectDetailsComponent {
project: Object = {};
constructor(private _api: ProjectsMainApi, private _params: RouteParams) {
this._api.getSinglePortfolio(_params.get("id")).then(
(res) => {
this.project = res.project;
},
(error) => {
console.error(error);
}
)
}
}
and my service is as follows:
import {Http, Headers, Response} from "#angular/http"
import {Injectable} from "#angular/core"
import {IProjectsMain, ISingleProject} from "../interfaces/AvailableInterfaces"
import 'rxjs/Rx';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
#Injectable()
export class ProjectsMainApi {
apiUrl: string = "http://www.example.org/api/projects";
headers: Headers = new Headers;
project$: Observable<IProjectsMain[]>;
private _ProjectsMainObserver: Observer<IProjectsMain[]>;
private _dataStore: {
project: IProjectsMain[]
};
constructor(private _http: Http) {
this.headers.append('Content-Type', 'application/x-www-form-urlencoded');
this.headers.append('X-Requested-With', 'XMLHttpRequest');
this.project$ = new Observable<IProjectsMain[]>(observer => this._ProjectsMainObserver = observer).share();
this._dataStore = { project: [] };
}
public getProjectsMain() {
this._http.get(this.apiUrl).map(response => response.json()).subscribe(data => {
this._dataStore.project = data.project;
this._ProjectsMainObserver.next(this._dataStore.project);
}, error => console.log('Could not load projects.'),
() => "done");
}
public getSinglePortfolio(id) {
console.log("the id is" + id);
return new Promise((resolve, reject) => {
this._http.get(this.apiUrl + "/" + id).map((res: Response) => res.json()).subscribe(
(res) => {
//console.log(res);
resolve(res);
}, (error) => {
reject(error);
}
);
})
}
}
and the function being called in this component is getSinglePortfolio(id)
and the jason
{"project":[{"id":1,"title":"fdgdfgdfg","slug":"sdfgsdfgsdfg" }, {"id":2,"title":"fdgdfgdfg","slug":"sdfgsdfgsdfg" }]}
I think that it is typescript compiler error.
You could define custom interface for that:
import {Component} from '#angular/core';
import {ProjectsMainApi} from "../../../services/projects-main";
import { RouteConfig, RouteParams, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '#angular/router-deprecated';
declare var jQuery: any;
interface ProjectResult {
project: Object
}
#Component({
...
and then specify type for res parameter:
this._api.getSinglePortfolio(_params.get("id")).then(
(res: ProjectResult ) => {
this.project = res.project;
},
(error) => {
console.error(error);
}
)
Full component code:
import {Component} from '#angular/core';
import {ProjectsMainApi} from "../../../services/projects-main";
import { RouteConfig, RouteParams, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '#angular/router-deprecated';
declare var jQuery: any;
interface ProjectResult {
project: Object
}
#Component({
selector: 'projects',
templateUrl: './app/components/Projects/details/project-single.html',
directives: [ROUTER_DIRECTIVES]
})
export class ProjectDetailsComponent {
project: Object = {};
constructor(private _api: ProjectsMainApi, private _params: RouteParams) {
this._api.getSinglePortfolio(_params.get("id")).then(
(res: ProjectResult) => {
this.project = res.project;
},
(error) => {
console.error(error);
}
)
}
}