Commit ff58b6fd authored by Florent Chehab's avatar Florent Chehab

Cleaned MyComponent solves #23

parent 6dfa5edc
...@@ -9,74 +9,70 @@ class MyComponent extends Component { ...@@ -9,74 +9,70 @@ class MyComponent extends Component {
__apiAttr = null; __apiAttr = null;
ignoreInvalidation = false; ignoreInvalidation = false;
getFetchedData(prop) { constructor(props) {
return this.props[prop].fetched.data; super(props);
}
// a little bit of optimization for later
getAllFetchedData() { this.fetchAbleProps = Array();
let out = Object() if (typeof props != 'undefined') {
const { props } = this; const { fetchData } = props;
for (let prop_key in props) { for (let propKey in fetchData) {
let prop = props[prop_key]; this.fetchAbleProps.push(propKey);
if (prop === Object(prop) && 'fetched' in prop) {
out[prop_key] = prop.fetched.data;
} }
} }
return out;
} }
joinCampus(campus) { // React default functions override
const { universities, countries, cities } = this.getAllFetchedData(); componentDidMount() {
let res = Object.assign({}, campus); //copy for safety this.loadPropsIfNeeded();
res.university = universities[campus.university]; this.myComponentDidMount();
res.city = cities[campus.city] this.forceUpdate(); // bug otherwies
res.country = countries[res.city.country]
return res;
} }
myComponentDidMount() { };
getUnivCityAndCountry(univId) { shouldComponentUpdate(nextProps, nextState) {
const univMainCampus = this.findMainCampus(univId); if (this.nextProps && typeof this.nextProps.visible != 'undefined' && !this.nextProps.visible) {
const cities = this.getFetchedData("cities"); // don't rerender components that won't be visible.
const countries = this.getFetchedData("countries"); return false;
const city = cities[univMainCampus.city]; }
const country = countries[city.country]; if (this.props.visible === false && !this.nextProps) {
return { city, country } // don't rerender components if it is still not visible
return false;
}
// if (this.nextProps && typeof this.nextProps.visible != 'undefined' && this.nextProps.visible) {
// // render if nextprops should be visible
// return true;
// }
return this.myShouldComponentUpdate(nextProps, nextState);
} }
myShouldComponentUpdate(nextProps, nextState) { return true; }
findMainCampus(univId) { componentDidUpdate(prevProps, prevState, snapshot) {
const mainCampuses = this.getFetchedData('mainCampuses'); // TODO ajouter expire date
for (let main_campus_pk in mainCampuses) { this.loadPropsIfNeeded();
const campus = mainCampuses[main_campus_pk] this.myComponentDidUpdate(prevProps, prevState, snapshot);
if (campus.university == univId) {
return campus;
}
}
return null;
} }
myComponentDidUpdate() { };
// General work on fetcheable props
checkProps(val) { checkProps(val) {
const { props } = this; return this.fetchAbleProps.some((propKey) => {
for (let el in props) { return this.props[propKey][val]
let prop = props[el]; })
if (prop === Object(prop) && val in prop && prop[val]) {
return true;
}
}
return false;
} }
checkPropsHasError() { checkPropsHasError() {
const { props } = this; for (let idx in this.fetchAbleProps) {
for (let prop_key in props) { const propKey = this.fetchAbleProps[idx];
let prop = props[prop_key]; const prop = this.props[propKey];
if (prop === Object(prop) && 'fetchHasError' in prop) {
if (prop.fetchHasError.status) { if (prop.fetchHasError.status) {
if (prop_key in this.customErrorHandlers) { if (propKey in this.customErrorHandlers) {
console.log("icicicicici"); console.log("icicicicici");
return this.customErrorHandlers[prop_key](prop.fetchHasError.error); return this.customErrorHandlers[propKey](prop.fetchHasError.error);
} else { } else {
return true; return true;
}
} }
} }
} }
...@@ -95,71 +91,93 @@ class MyComponent extends Component { ...@@ -95,71 +91,93 @@ class MyComponent extends Component {
return this.checkProps('isSaving'); return this.checkProps('isSaving');
} }
loadPropsIfNeeded(dontFetch = false) { propIsUsable(propKey) {
let propsLoaded = true; const prop = this.props[propKey];
if (this.checkPropsHasError()) { if ((!prop.fetched.fetchedAt) || (!this.ignoreInvalidation && prop.invalidated)) {
return false; return false
} }
return true;
}
propsThatNeedToBeFetch() {
return this.fetchAbleProps.filter((propKey) => {
const prop = this.props[propKey];
const { props } = this; if (!this.propIsUsable(propKey)) {
for (let prop_key in props) { if (!prop.fetchHasError.status && !prop.isLoading) {
let prop = props[prop_key]; return true;
if (prop === Object(prop) && 'fetched' in prop) {
if ((!prop.fetched.fetchedAt) || (!this.ignoreInvalidation && prop.invalidated)) {
propsLoaded = false;
if (!dontFetch) {
if (!prop.isLoading) {
if (this.__apiAttr && this.__apiAttr[prop_key]) {
props.fetchData[prop_key](this.props[this.__apiAttr[prop_key]]);
} else {
props.fetchData[prop_key]();
}
}
}
} }
} }
} return false;
return propsLoaded; })
}
loadPropsIfNeeded() {
this.propsThatNeedToBeFetch().map((propKey) => {
if (this.__apiAttr && this.__apiAttr[propKey]) {
this.props.fetchData[propKey](this.props[this.__apiAttr[propKey]]);
} else {
this.props.fetchData[propKey]();
}
})
} }
allFetchedDataAreReady() { allFetchedDataAreReady() {
return this.loadPropsIfNeeded(true); return !this.fetchAbleProps.some((propKey) => {
if (!this.propIsUsable(propKey)) {
return true;
}
return false;
})
} }
componentDidMount() { getFetchedData(propKey) {
this.loadPropsIfNeeded(); return this.props[propKey].fetched.data;
this.myComponentDidMount();
this.forceUpdate(); // bug otherwies
} }
myComponentDidMount() { };
shouldComponentUpdate(nextProps, nextState) { getAllFetchedData() {
if (this.nextProps && typeof this.nextProps.visible != 'undefined' && !this.nextProps.visible) { let out = Object()
// don't rerender components that won't be visible. this.fetchAbleProps.map((propKey) => {
return false; out[propKey] = this.props[propKey].fetched.data;
} })
if (this.props.visible === false && !this.nextProps) { return out;
// don't rerender components if it is still not visible
return false;
}
// if (this.nextProps && typeof this.nextProps.visible != 'undefined' && this.nextProps.visible) {
// // render if nextprops should be visible
// return true;
// }
return this.myShouldComponentUpdate(nextProps, nextState);
} }
myShouldComponentUpdate(nextProps, nextState){ return true; }
componentDidUpdate(prevProps, prevState, snapshot) {
// TODO ajouter expire date // utilities functions shared by subclasses
this.loadPropsIfNeeded(); joinCampus(campus) {
this.myComponentDidUpdate(prevProps, prevState, snapshot); const { universities, countries, cities } = this.getAllFetchedData();
let res = Object.assign({}, campus); //copy for safety
res.university = universities[campus.university];
res.city = cities[campus.city]
res.country = countries[res.city.country]
return res;
}
getUnivCityAndCountry(univId) {
const univMainCampus = this.findMainCampus(univId);
const cities = this.getFetchedData("cities");
const countries = this.getFetchedData("countries");
const city = cities[univMainCampus.city];
const country = countries[city.country];
return { city, country }
}
findMainCampus(univId) {
const mainCampuses = this.getFetchedData('mainCampuses');
for (let mainCampusPk in mainCampuses) {
const campus = mainCampuses[mainCampusPk]
if (campus.university == univId) {
return campus;
}
}
return null;
} }
myComponentDidUpdate() { };
// Override of the default render behaviour to wait for data to arrive.
render() { render() {
if (this.checkPropsHasError()) { if (this.checkPropsHasError()) {
return <p>Sorry! There was an error loading the items</p>; return <p>Une erreur est survenue lors du téléchargement des données. Merci de recharger la page et si l'erreur persiste, merci de contacter les administrateurs du site.</p>;
} }
if (!this.allFetchedDataAreReady()) { if (!this.allFetchedDataAreReady()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment