Typescript Error TS2339: Property 'project' does not exist on type '{}' - angularjs-directive

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);
}
)
}
}

Related

How to access the ID without using json(), while using HttpClient

I need to access the id of the object here. However, could not use json(), as it's in HttpClient. Please advise, what could be a solution. The error I'm facing is: "TS2339: Property 'json' does not exist on type 'Object'."
And without Json, the error is with 'id'. i.e. "TS2339: Property 'id' does not exist on type 'Object'." (Please refer to: post['id'] = response.json().id;)
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
// const headers = { 'Content-Type': 'application/json' };
#Component({
selector: 'posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.css'],
})
export class PostsComponent {
posts: any[];
private url = 'https://jsonplaceholder.typicode.com/posts';
constructor(private http: HttpClient) {
http
.get(this.url) //{ headers }
.subscribe((response: any[]) => {
this.posts = response;
});
}
createPost(input: HTMLInputElement) {
let post = { title: input.value };
this.http.post(this.url, JSON.stringify(post)).subscribe((response) => {
post['id'] = response.json().id;
console.log(response);
});
}
}
try something like below :
createPost(input: HTMLInputElement) {
let post = { title: input.value };
this.http.post(this.url, JSON.stringify(post)).subscribe((response:any) => {
post['id'] = response.id;
console.log(response);
});
}
take a look at this sample :
https://stackblitz.com/edit/angular-ivy-o8b7ri?file=src%2Fapp%2Fapp.component.ts

Get data from json file in Angular 2

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;
}

how to refresh data every 5 second using observable

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.

Nativescript application-settings to persist a JSON value

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")
}
);

angular2: Supplied parameters do not match any signature of call target, even though i have all the needed params

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