In my Angular 2 application I have a function :
notification : Array<any>;
......
......
getNotification () {
return setTimeout(() => {
this.AppbankService.notify(this.user.NameId)
.subscribe(
(response) => {
if (response.status === 200) {
this.notifications.push(response.json());
console.log(typeof(this.notifications));
}
this.getNotification();
}
)
},5000)}
In this function, I get notification from the server every 5 seconds and try to push them to an array, but a have this:
error app.module.ts:104 error : TypeError: Cannot read property 'push' of undefined(…)
Any suggestion?
Change
notification : Array<any>;
to
notification : Array<any> = [];
I had the same issue of push string message and my issue has resolved by below code.
messages: Array<string> = [];
add(message: string): void {
this.messages.push(message);
}
I faced the same issue and then discovered that I forgot to initialize my service method itself and its type was set to any.
Related
I'm getting the following error:
**Error1:** Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables, such as Arrays. Did you mean to use the keyvalue pipe?
**Error2:** this.blogs.push is not a function
My code looks like this:
export class BlogComponent {
blogs: Array<blogType>;
constructor() {
this.blogs = new Array<blogType>();
}
ngOnInit() {
this.blogs = JSON.parse(localStorage.getItem("blogs")!);
}
addBlog(title: any, content: any) {
let blog = new blogType(title.value, content.value);
if (localStorage.getItem('blogs')) {
this.blogs = JSON.parse(localStorage.getItem('blogs')!);
}
this.blogs.push(blog); //error occurs because of that line. Runtime error
localStorage.setItem('blogs', JSON.stringify(this.blogs));
title.value = '';
content.value = '';
alert('Blog Added!');
}
I am trying to take data from the "blog" array and push it to the "blogs" array in order to store it in the localstorage. Yet I get an error because of the folowing line: this.blogs.push(blog);
Check the contents of LocalStorage for null before you parse it and assign to this.blogs:
ngOnInit() {
var current = localStorage.getItem('blogs');
if (current !== null) {
this.blogs = JSON.parse(current);
}
console.log('this.blogs is: ' + this.blogs);
}
I have a dbService that calls the database!
//DB service code -----------------------
private changedEvents = new BehaviorSubject<IEvent[]>(null);
broadCastEvents = this.changedEvents.asObservable();
getEvents() {
this.http.get<IEvent[]>(this.configUrl + 'Event/GetEvents').subscribe(
(data: IEvent[]) => {
this.changedEvents.next(data)
});
}
In my component on ngOnInit I starts listening to this
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data;
})
// this.dbService.getEvents();
}
Now all of this working like a charm! But now I'm only interested in records where this.events.type == 2
I tried by a standard filtering like below!
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => event.eventTypeRefId == 2);
})
// this.dbService.getEvents();
}
But it results in the following Error!? Any ideas how to this in a better way (that works :-))
core.js:6241 ERROR TypeError: Cannot read property 'filter' of null
at SafeSubscriber._next (start-training.component.ts:26)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
at SafeSubscriber.next (Subscriber.js:122)
at Subscriber._next (Subscriber.js:72)
at Subscriber.next (Subscriber.js:49)
at BehaviorSubject._subscribe (BehaviorSubject.js:14)
at BehaviorSubject._trySubscribe (Observable.js:42)
at BehaviorSubject._trySubscribe (Subject.js:81)
at BehaviorSubject.subscribe (Observable.js:28)
at Observable._subscribe (Observable.js:76)
ngOnInit(): void {
this.dbService.broadCastEvents.pipe(filter(event => event.eventTypeRefId == 2)).subscribe(data => {
this.events = data
})
// this.dbService.getEvents();
}
Reference:
https://rxjs-dev.firebaseapp.com/guide/operators
There are multiple ways for it. One way is to use array filter like you did. Other way would be to use RxJS filter pipe as shown by #enno.void. However both these methods might still throw an error when the notification is null. And since the default value of your BehaviorSubject is null, there is high probability of hitting the error again.
One workaround for it is to use ReplaySubject with buffer 1 instead. It's similar to BehaviorSubject in that it holds/buffer the last emitted value and emits it immediately upon subscription, except without the need for a default value. So the need for initial null value is mitigated.
Try the following
private changedEvents = new ReplaySubject<IEvent[]>(1);
broadCastEvents = this.changedEvents.asObservable();
...
Now the error might still occur if you were to push null or undefined to the observable. So in the filter condition you could check for the truthiness of the value as well.
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => {
if (event) {
return event.eventTypeRefId == 2;
}
return false;
});
});
}
I am trying to create a design for tags of entities in PouchDB with ReactJS. I managed to save my design using the put function, but when I query my design, the response is just an empty array and I am getting following error in console:
TypeError: Cannot read property 'emit' of undefined
I think the problem is in my function that I later use as a map parameter to my design variable:
function emitTagsMap(doc)
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
/* Here is probably the problem - this.db is undefined */
this.db.emit(x, null);
});
}
}
};
this.db is declared in constructor:
constructor(service, name)
{
if (!service || !name) throw new Error("PouchDatabase initialized incorrectly");
this.name = name;
this.db = new PouchDB(name);
this.service = service;
this.tagsView();
}
Please bare in mind that I am completely new to PouchDB.
Any ideas how can I initialize the emit function?
Thank you in advance.
I assume, that your function is a part of a JavaScript class (otherwise you have to explain the idea with this). In ES6, you have to bind this to your regular functions. You have two options:
First - bind it via constructor:
constructor() {
this.emitTagsMap = this.emitTagsMap.bind(this);
}
Second - declare the function as an arrow one. This way, react will bind it for you:
emitTagsMap = (doc) =>
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
/* Here is probably the problem - this.db is undefined */
this.db.emit(x, null);
});
}
}
};
You don't need to call emit over the database object.
Try this:
function emitTagsMap(doc)
{
if (doc !== undefined)
{
if (Array.isArray(doc.tags))
{
doc.tags.forEach(x =>
{
emit(x, null);
});
}
}
};
According to the PouchDB docs a design document is formed like this:
// first create a new design doc and pass your map function as string into it
var ddoc = {
_id: "_design/my_index",
views: {
by_name: {
map: "function (doc) { if (doc !== undefined) { if (Array.isArray(doc.tags)) { doc.tags.forEach(x => { emit(x, null); }); } } }"
}
}
};
// save it
db.put(ddoc).then(function () {
// success!
}).catch(function (err) {
// some error (maybe a 409, because it already exists?)
});
//Then you actually query it, by using the name you gave the design document when you saved it:
db.query('my_index/by_name').then(function (res) {
// got the query results
}).catch(function (err) {
// some error
});
https://pouchdb.com/guides/queries.html
I have the following method which isn't working correct:
getProducts(): Observable<Product[]> {
let PRODUCTS: Product[];
this.http.get(this.base_url + "api/products")
.subscribe(
(data) => {
for(var i in data) {
PRODUCTS.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
},
(error) => {
console.log(error);
});
return of(PRODUCTS);
}
The error I'm getting is this:
TypeError: Cannot read property 'push' of undefined
Now, I know that the PRODUCT array is not accessable from within the subscribe function, but I cannot get the correct solution for it.
Can anyone help me with that. I want to return an Observable<Product[]>.
Thank you in advance!
Edit: Updated to account for the fact that the API seems to return an array-like object rather than a true array.
You want to use map:
getProducts(): Observable<Product[]> {
return this.http.get(this.base_url + "api/products")
.map(data => {
let products = [];
for (let i in data) {
products.push(new Product(data[i].id, data[i].name, data[i].category, data[i].description, data[i].price, data[i].amount));
}
return products;
})
.do(null, console.log);
}
Since #pixelbit's comment keeps getting upvotes despite being wrong, here's an example showing why it is wrong:
// Fakes a HTTP call which takes half a second to return
const api$ = Rx.Observable.of([1, 2, 3]).delay(500);
function getProducts() {
let products = [];
api$.subscribe(data => {
for (let i in data) {
products.push(data[i]);
}
});
return Rx.Observable.of(products);
}
// Logs '[]' instead of '[1, 2, 3]'
getProducts().subscribe(console.log);
I wrote a injectable service in which i want to return "display" in my data and i done it sucessfully as follows,
export class GetAllList {
str = localStorage.getItem('social');
loc = JSON.parse(this.str);
id = this.loc._id;
private _productUrl = 'http://localhost:3000/getprofiledetails/'+this.id;
constructor(private _http: Http) { }
getList(): Observable<IDetails[]> {
return this._http.get(this._productUrl)
.map((response: Response) => {
return response.json().data.display;
});
}
}
Here i am subscribing to it,
this._profileservice.getList()
.subscribe(
details1 => this.details1 = details1);
console.log("displaystas:"+this.details)
The problem is,my console is displaying undefined?so how can i see my display value in my console?Can anyone suggest me help.Thank you.
You are printing wrong variable (details instead of details1) and you are missing {}:
this._profileservice.getList()
.subscribe(
details1 => {
this.details1 = details1;
console.log("displaystas: " + this.details1)
}