How to Make Sure Data in Variable Is Loaded Before Using It

Wait until scope variable is loaded before using it in the view in angular.js

Have the validatedPermission function return false when allPermissions hasn't been loaded. That way the element with your ng-show won't be displayed until allPermissions has been loaded.

Alternatively, put an ng-show="allPermissions" on the enclosing <ul> or <ol>.

React : How to make sure that requested data are available before rendering?

I usually use a spinner to indicate that the widget is loading:

render() {
return this.state.loading ? (
<div className="spinner">
<Spinner />
</div>
) : this.renderView();
}

renderView() does the actual rendering when state.loading is false. When state.loading is true, a spinner is displayed.

In componentWillMount, I set loading to true before making the API call.

componentWillMount() {
this.setState({loading: true});
ajaxCall().then(responses => {
// process response
this.setState({loading: false});
});
}

Async with useEffect and loading data into variables

Your code makes perfect sense. Your component cannot know the value of something that needs to be fetched on mount.

The classic way to handle that kind of situation is using a state as follow:

const MyComponent = () => {
const [isLoading, setIsLoading] = React.useState(true);
const [error, setError] = React.useState();
const [data, setData] = React.useState([]);

React.useEffect(() => {
getAudience().then((fetchedData) => {
setData(fetchedData);
setIsLoading(false);
}).catch((err) => {
setError(err.toString());
setIsLoading(false);
});
}, [])

if (!!error) return <span>Error: {error}</span>;

if (isLoading) return <span>Loading...</span>;

// Here you do stuff on your data since you know it is ready

return <span>{JSON.stringify(data, null, 2)}</span>;
}

You might consider creating a reusable hook to reduce code boilerplate. There are existing hooks created by the community for Supabase.

Example: https://jsfiddle.net/5nhteu9v/

React: How to wait data before using this.state.x into a function?

You're going to need to conditionally render. Provide a loading state to be loaded prior to asynchronously required data. You'll want something like the following:

class WrapperComponent extends PureComponent {
constructor(props) {
super(props);

this.state = {
isLoaded: false,
data: null
};
}

componentDidMount() {
MyApiCall.then(
res => this.setState({
// using spread operator, you will need transform-object-rest-spread from babel or
// another transpiler to use this
...this.state, // spreading in state for future proofing
isLoaded: true,
data: res.data
})
);
}

render() {
const { isLoaded, data } = this.state;
return (
{
isLoaded ?
<PresentaionComponentThatRequiresAsyncData data={ data } /> :
<LoadingSpinner /> // or whatever loading state you want, could be null
}
);
}
}

How to ensure all JS files are loaded before executing a task when including JS files with javascript

There is an event load that is triggered once your <script src="..."> has been loaded(and since JS is single-threaded it also means it has been executed as well)

var body = document.body;

var scriptEl = document.createElement('script');

scriptEl.src = 'https://underscorejs.org/underscore-min.js';

scriptEl.addEventListener('load', function() {

console.log('Underscore version is ' + _.VERSION);

});

body.appendChild(scriptEl);

Nuxt page HTML is loaded before data

You could use the fetch hook to dispatch fetchProducts:

<script>
export default {
fetch() {
return this.$store.dispatch('fetchProducts')
}
}
</script>

In your template, use the $fetchState.pending flag to prevent rendering the data elements until ready:

<template>
<div>
<Loader v-if="$fetchState.pending" />
<Error v-else-if="$fetchState.error" />
<Product v-else v-for="product in products" v-bind="product" />
</div>
</template>

demo

Angular - Wait until I receive data before loading template

After studying the different approaches that people gave me, I found the solution on the async pipe. But, it took me a while to understand how to implement it.

Solution:

// Declaring the Promise, yes! Promise!
filtersLoaded: Promise<boolean>;

// Later in the Component, where I gather the data, I set the resolve() of the Promise
this.getFiltersSubscription = this.getFilters().subscribe(
(filters) => {
this.filters = filters;
log.info('API CALL. getting filters');

this.filtersLoaded = Promise.resolve(true); // Setting the Promise as resolved after I have the needed data
}
);

// In this listener triggered by the dynamic components when instanced,
// I pass the data, knowing that is defined because of the template change

// Listens to field's init and creates the fieldset triggering a service call
// that will be listened by the field component
this.iboService.initIBOsFilters$.subscribe(
(fieldName) => {
if (fieldName === 'IBOsRankSelectorFieldComponent') {
log.data('inside initIBOsFilters$ subscription, calling updateIBOsFilters()', fieldName);
this.iboService.updateIBOsRankList(this.filters['iboRank'].data);
}
}
);

In the template, I use the async pipe that needs an Observable or a Promise

<div *ngIf="filtersLoaded | async">
<div [saJquiAccordion]="{active: group.value['collapsed']}" *ngFor="let group of filterGroupsTemplate | keysCheckDisplay;">
<div>
<h4>{{group.key | i18n}}</h4>
<form id="ibo-{{group.key}}" class="form-horizontal" autocomplete="off" style="overflow: initial">
<fieldset *ngFor="let field of group.value | keys">
<ng-container *ngComponentOutlet="fieldSets[field.value.template];
ngModuleFactory: smartadminFormsModule;"></ng-container>
</fieldset>
</form>
</div>
</div>
</div>

NOTE:

  • async pipe need an Observable or a Promise from what I understood, that's why the only way to make it work was by creating a Promise
  • I didn't use the resolver approach because it's used when you arrive to the component through Angular's routing. This component is part of a larger component and it's not instanced through routing like any other normal component. (Tried that approach though, worked a bit with it, didn't do the job)


Related Topics



Leave a reply



Submit