I'm using ionic's events to pass data from page to page. In this instance I'm passing an array to another page, let's say with two objects. The data I'm wanting to add to is called dataOne and I'm using a life cycle function so that when the user enters the page they will be automatically tested from this function whether or not there is an event to be concatenated onto dataOne. The issue is, the data isn't being added. I'm able to retrieve the data but nothing happens to the table, as I'm still getting the same result.
ts
ionViewWillEnter(){
this.events.subscribe('market', (dataTwo) => {
return this.dataOne = this.dataOne.concat(dataTwo)
})
}
What is 'Market' ? dataOne is array? In my opinion,
dataOne: any[]=[];
...
this.events.subscribe((dataTwo) =>{
this.dataOne.push(dataTwo.market); // if market you want to catch data
}
Related
In my service file, I have a get method to return data form a collection to an array. I want to have another method in my component (front-end controller) which need to access those data from the data base before the page loads. So I use it like below (books is the array to store data from the database)
refreshBookList() {
this.bookService.getBookList().subscribe((res) => {
this.books = res as Book[];
console.log(this.books);});
}
I need to do this when the page loads. so I call it like
ngOnInit() {
this.refreshBookList();
}
But it only returns an empty array. The data gets added to the array only if the method is called from a button click in the interface. Is there any way I could get the result at page initialization.
Maybe you can try to call the method inside AfterViewInit
I am new to Angular and this is my first app. I have a parent component which gets data from an API using service. With the response from the service, I create an array and pass it as attribute to a child component. In the child component, I have the follow ngOnChange event
ngOnChanges(changes: any) {
console.log("Mode total in mode", this.modeTotal);
this.modeTotal.map(mode => {
console.log("For each");
this.doughnutChartLabels.push(mode.name);
this.doughnutChartData.push(mode.total);
console.log(`Loop inside onChange Name: ${mode.name} and Total: ${mode.total}`);
});
console.log("DoughnutChartLabels", this.doughnutChartLabels);
console.log("DoughnutChartData", this.doughnutChartData);
}
The problem I am facing is the console above and below the map function is working, printing the content of modeTotal, doughnutChartLabels and doughnutChartData but not the string inside the map function. And the modeTotal has the array of data which I expect to be returned.
What am I missing?
Note: I push data into the modeTotal from another component which receives data from an API. The modeTotal is not getting updated even when new data is pushed into it.
The change event will not occur on an array when a new data is pushed into it since the variable is referring to the same object. Try adding a local variable to monitor the push changes.
I have an angular 4 application in which service file which is subscribed to
Component file I need to have Typescript data fields to set from this data from the subscribed method call.
PROBLEM - if console.log is empty ... then seems I need to wait somehow on the data, but how do I do this, example somewhere?
Data Array
sessionTrackers: ISessionTracker[] = [];
method that subscribes to service call to web api
this.trackerService.getSessionTracker()
.subscribe(sessionTrackers => {
this.sessionTrackers = sessionTrackers;
this.filteredSessions = this.sessionTrackers;
console.log('real data in subscribe', this.sessionTrackers);
},
error => console.log('error : ' + <any>error)
);
Notice that I have sessionTrackers which INSIDE the method it works
However when OUTSIDE the method it is empty.
Thus its a race condition in which this asynch. operation is not ready
This outside of method showing empty array
console.log('real data', this.sessionTrackers);
I assume it will probably "work" in html , but I have fields in typescript I need to set for a reactive form
id: number
How can I achieve the data persistence before setting these fields?
I am fetching objects from an API simply with
getData() {
fetch('API_URL').then(res => res.json()).then(data => {
this.setState({ jobs: data.jobs });
}).catch(console.log);
}
componentDidMount() {
this.getData();
}
But I want to be able to click a button to load more objects.
I guess that I should create the API such that it only prints e.g. 10 objects at a time and keeps a variable "pageNumber" and if I click the "load more" button, it should fetch from next page and append the new objects.
Is this the right approach? Or can I simply load thousands of objects when mounting the component and use React to limit how many are seen? I guess this would be a very inefficient way to fetch the data, but I am not really sure how well React handles this.
Can I, for instance, in my API just keep print X number of objects and in my fetch request decide how many objects are loaded? So when I have pressed "load more" 2 times, the API endpoint will return 30 objects instead of only 10 - even though the first 20 have already been fetched before?
I have tried searching for pagination in React, but I only get a lot of pagination libraries. I just want to understand the very basic initial fetching and the fetching following clicking load more.
Edit
But if I have an API endpoint which returns something like
{
page: 1,
objectsPerPage: 10,
numPages: 30,
objects: [
...
]
}
and I am initially retrieving the objects on page 1, and every time I click "Load more", I increase the page number and append the objects on the next page (with this.setState({ jobs: this.state.jobs.concat(data.jobs) }); where data.jobs is the list of objects on the next page, then I would be afraid that new objects are created in the database, so which objects belong to which page is completely screwed up and not all or some duplicates are shown.
Yes, it is the right approach to have a pageNumber on the API, so you only look for the registers you don't have.
On the other size if your data is not too big you can make the fake pagination having all the objects in memory and only showing the ones that you are interested in.
I don't recommend to increase the number of objects you are looking for because you are not getting the advantage of the ones you have already fetched and everytime you increase the number, the request will last more and more.
I'm pretty new to Backbone.js, loving it so far, but I'm having a little trouble trying to get relational data to render.
Within my Backbone view (called ImagesView) I have the following code:
// Render it
render: function () {
var self = this;
// Empty the container first
self.$el.html("")
// Loop through images
self.collection.each(function(img){
// convert `img` to a JSON object
img = img.toJSON()
// Append each one
self.$el.append(self.template(img))
}, self)
}
There are 3 images in the collection, and they are templated correctly with the above code. Within the img object is a user attribute, containing the User ID. I'm trying to return the user's details, and use these within the template instead of the ID. I'm doing that using the code below:
// Render it
render: function () {
var self = this;
// Empty the container first
self.$el.html("")
// Loop through images
self.collection.each(function(img){
// convert `img` to a JSON object
img = img.toJSON()
/* New code START */
// Each img has a `user` attribute containing the userID
// We'll use this to get their details
$.getJSON('/user/' + img.user, {}, function(json, textStatus) {
img.photographer = {
id: json.id,
username: json.username,
real_name: json.real_name
}
/* Moved 1 level deeper */
// Append each one
self.$el.append(self.template(img))
});
/* New code END */
}, self)
}
When I do this, the user's details are returned correctly and inserted into the template, but I now get 3 of each image returned instead of 1 (i.e. 9 in total), in a completely random order. What am I doing wrong? I'm open to using Backbone methods instead of the getJSON if that will make it easier, I just couldn't get it to work myself. I'm using underscore.js for the templating
The random order is likely caused by the requests being fired at very close intervals and responses returning out of the order they were fired in. I'm not sure why you're getting the multiple things, but if your template renders everything and you're calling that 3 times that could be it?
Anyway where I think you're going wrong is putting the responsibility of loading data into the render method. You'd want this to be abstracted so you have a good separation between data concerns and template concerns. As the ordering of the data is of interest, you'll want all 3 requests to have loaded before rendering. There's two different approaches you could take to this depending on if prior to loading this data you have sufficient data to render the view:
If you're waiting on all the data prior to rendering the view then you would want to render a different view (or template of this view) whilst the data is loaded and then replace that with a view showing all the data once it is loaded.
If you have sufficient data to render the view and what you are loading is supplementary, you'd want to render the view with the data you have in render and then once the other data is loaded use a custom method to modify the rendered view to include your data.
If you want to find out when all 3 requests are complete you can use http://api.jquery.com/jquery.when/