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 anObservable
or aPromise
from what I understood, that's why the only way to make it work was by creating aPromise
- 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
How to Stop an Infinitely Rotating Image? and How Does One Implement Removeallanimations
My Button Is Centered for iPhone 6 and 6 Plus, But Not for iPhone 5
Store Data in Custom Class Array in Core Data
Code Only Retrieving One Value from Data in Firebase
Could Not Cast Value of Type Uiview to [Customview] Using Xib
How to Unpack Multiple Levels of Nested JSON in Firebase Database
Avaudioplayer.Play() Works But Avaudioplayernode.Play() Fails
Swift Decodable, Endpoint Returns Completely Different Types
Moving an Object Across the Screen at a Certain Speed.(Sprite Kit)
Tabview, Tabitem: Running Code on Selection or Adding an Ontapgesture
Value of Type 'Authdataresult' Has No Member 'Uid'
Don't Delete Some Rows from Uitableview
How to Get Exactly the Same Point on Different Screen Sizes