Vue Material - MdTable initialization error in data fetching - javascript

As I stated here, I'm trying to fetching remote data to initialize MdTable component, but the process throws a null error. Data being fetched from a MySQL DB, part of a Laravel 5.6 API project.
After a deep analysis, I assumed that the issue is caused by a premature initialization of component itself, before the finish of fetching process. So, the model that manage component data results empty, and rendering crashes.
I tried different ways: the navigation is managed by Vue-Router, so both Before/After Navigation data fetching techniques has been tested, and the result is the same. Using props from parent component, as well as defining component navigation guards, seems to be useless in order to avoid the problem.
I think the solution could be to hold the component rendering until data being fetched. But I really don't get how. I tried with beforeCreate()/created() too, but none of them helped.
I'm stuck from many days in this situation, some help or suggestion to try at last a new direction is really appreciated.
Thanks in advance for help.

As I stated here, Due to a syntax error on my implementation:
[...]
<md-table-cell v-for="(val, i) in item" :key="val.id" v-if="(i !== 'id') && (i !==
'estensione_garanzia') && (i !== 'note')"
[...]
The attribute :key="val.id" is misconfigured. In this case I'm iterating an array of objects - without nested of them - so there's no sub-property id on selected element. For more information the official doc shows a complete example
By changing the attribute like this:
:key="val.id"
Everything works fine.

Related

can't access array of objects in object

I'm baffled about why I'm getting an error when trying to access an array inside of an object in ReactJS.
I am using Redux to store an object in State.
I have a success function that allows the page to render, so by the time I get to this object it has for sure loaded. (I noticed a ton of similar questions to this where that's usually the problem).
When I do this I get the proper results:
const { events } = this.props
console.log(JSON.stringify(events.listSignup))
{"data":[{"eventID":"264712106049274377","name":"BookOne","email":null,"verify":null,"privacy":null,"order":null,"group":null},{"eventID":"264712106049274377","name":"BookTwo","email":null,"verify":null,"privacy":null,"order":null,"group":null}]}
I can see that the array "data" exists, but when I try:
console.log(JSON.stringify(events.listSignup.data[0].name))
or
console.log(JSON.stringify(events.listSignup.data[0]))
I get "TypeError: Cannot read property 'data' of undefined"
I'm at my wits end trying to figure out what's going on. Any advice would be much appreciated!
You're right to be baffled, because what you [think you] have observed isn't possible.
This happens a lot to me as a developer, and my advice is that when this happens, trust your knowledge (you know this isn't possible!) and double check what you are seeing.
I suspect that the first time your component renders, this.props.events is undefined, but then it very quickly re-renders with this.props.events being set.
I would suggest adding back this line (without the others):
console.log(JSON.stringify(events.listSignup))
And scrolling up in your javascript console to see if you have any logs that are just displaying undefined. If so, you probably need to double check the logic which is preventing the page from rendering before you have successfully received the data, as I suspect that is where your problem is.

How to fix extra rendering of the page when accessing data from the Mobx store, after a request to the API?

I try in Mobx to make "isLoggedIn" variable that will display whether the user is logged (true) in or not (false).
To do this, I need to make a request to the server in order to authenticate the user. The problem is that when I access the "isLoggedIn" variable, it is still undefined, since the request has not yet ended. It is filled after the server has given an answer. Because of this, my component is rendered twice.
The screenshot shows my problem.
What is the best way to organize this? I’ve been stuck with this logic for several days now, and I can’t understand how I should do it better.
I tried different options for working with API, but I just can’t solve the problem. To better understand the problem, I downloaded the sample code into the https://codesandbox.io/s/mobx-85x7k
I want that when referring to "isLoggedIn" variable, that it contained data (true or false). I want to avoid extra page rendering.

Make properties lazy

I was reading the article on best practices here. And i came across the following lines:
A developer might attempt to set a property on your element before its definition has been loaded. This is especially true if the developer is using a framework which handles loading components, inserting them into to the page, and binding their properties to a model.
And the proposed solution to solve this problem was:
_upgradeProperty(prop) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
I have been trying the understand the scenario in which this would happens, and try to understand how this fragment of code solves this problem. I have trying to find any reference material around but wasnt able to find anything similar like this.
Please could someone explain this scenario and what problem are we trying to solve here.
Web Components doesn't fully initialize your element until you call customElements.define('custom-tag', CustomElement); however, any <custom-tag> exists in the DOM as an HTMLUnknownElement as soon as the page renders. So in the period of time between when the page renders and when you call customElements.define(...), it's possible for someone to call something like:
document.querySelector('custom-tag').someProperty = someValue
which would modify the property of the not-yet initialized CustomElement.
Why would this happen?
I think this would most likely come up as a side-effect of using Web Components with a frontend framework (Angular, Vue, etc). These frameworks often have initialization code that happens after render, and there may be situations where a user may not have sufficient control to prevent the framework from initializing before Web Components.
How does the code fragment solve the problem?
The fragment function, _upgradeProperty() is meant to be called within the connectedCallback(), which is called after the Web Component has been fully defined and attached to an existing element. If you have any custom setter in your class, like:
class CustomElement {
set someProperty(value) {
this._someProperty = value.toLowerCase();
}
}
Then it's possible the property was set before the setter existed, meaning the raw value was saved directly to the instance's someProperty property, instead of being converted to lowercase and saved to _someProperty. Deleting the property and reassigning it after the setter has been defined ensures that the value is properly processed (in this case, made lowercase and saved in the right location).

How does one run code in a Vue component only once per page (when more than one of the same component exists on that page)?

So I have a Vue component which has two functions. One attaches some data and populates various tags with that data, another gets the data from a json file and parses through it - applying it to the other function.
(pseudo-code ahead!)
mounted: function() {
function listBuilder(data) { some code }
$.get("some-json"), function (data) {
[some code...]
listBuilder(data);
}
}
On the page itself, this component exists twice.
<section>
<my-component type="map"></my-component>
</section>
<aside>
<my-component></my-component>
</aside>
One component renders out the data in map form, while the other renders it out as a list. This all works just fine & dandy, except that on the map the data is rendered 2x - because, as you might have guessed, the component's logic is run twice - getting the json twice and processing it twice.
Is there a native "Vue" way to have (or designate) the code in the component to only run once on a page? I have a rather (in my opinion), hacky way of avoiding this right now, by applying a property to one of the components ("dumb"), that essentially skips some of the logic via a check if that property exists. I feel there has got to be a more elegant and native way to handle this, however, but have come up dry in my google searches.
One possible way is to have the component data loading moved to another parent element. Other way of doing this is to have one global store (like vuex) and then load the data out of it. This is just the type of problem vuex is solving. If you don't want to use vuex just use the browser's Window.sessionStorage it is well supported and you can store all the data you need in it. It is session based so you won't need to load the information every time.
Well I'm sure you'll get different responses, but I would have to agree with #pinoyyid and suggest extracting http part into a service for start, and then I would implement Vuex ( centralized local data that can be fairly easily integrated with Vue ) and then use Vuex actions and getters to get and process data. This will completely separate your vue component from fetching and data processing. You will only fetch your data once and then use it as many times as you'd like. And last but not least testing will be possible unlike now.

Preventing UI flicker when loading async data in React.js

I have some data in IndexedDB, which can only be accessed asynchronously. I want to build a React.js UI using that data. The general idea is that I'll have multiple React components that load data from IndexedDB and display some UI based on that data, and the user will be able to switch between which component is currently displayed.
My concern is that I don't know how to elegantly accomplish this without some superfluous UI flickering. I can do my asynchronous data loading in componentDidMount and put the data in this.state, but then render will be called before it's finished, forcing me to either display nothing or display some placeholder data for a tiny fraction of a second while the data from IndexedDB is retrieved.
I'd rather have it not render until after my data from IndexedDB is loaded. I know it won't take long to load, and I'd rather the previous component continue to display while the new data loads, so there is just one flicker (old -> new) rather than two (old -> blank/placeholder -> new). This is more like how a normal web page works. When you click a link from one website to another, your browser doesn't instantly show a blank/placeholder screen while it waits for the server from the linked website to respond.
I'm thinking I could do my data loading outside of the React component before calling React.render and then passing it in via this.props. But that seems messy, because nesting components would become tricky and some of my components will be updating over time and pulling new data from IndexedDB, through the exact same code that initializes them. So it seems like an ideal use case for storing data in this.state because then I could update it within the component itself when I get a signal that new data is available. Initialization and updating would be as easy as calling a this.loadData() function that sets some values in this.state... but then I have the aforementioned extra flicker.
Does anyone have any better ideas? What's the canonical solution to this problem? Is it really to just have millisecond blank/placeholder flickers all over the place?
From the comments it sounds like the behavior you have in the previous implementation (waiting to navigate until you have fetched the necessary data) is the desired goal. If that's the case, the best way to do this without having the flickering would be to use some external object to manage the state and pass the data as props when it has been fetched.
React Router has a pretty good solution where it has the willTransitionTo hook to fetch data for a given component before navigating. This has the added benefit of allowing you to easily catch errors if something goes wrong.
Updated with new link:
https://github.com/reactjs/react-router

Categories