Skip to content

Instantly share code, notes, and snippets.

@webmasterdevlin
Created November 17, 2019 10:33
Show Gist options
  • Save webmasterdevlin/bf0c99939a6aca71672ebc71ec9a6938 to your computer and use it in GitHub Desktop.
Save webmasterdevlin/bf0c99939a6aca71672ebc71ec9a6938 to your computer and use it in GitHub Desktop.
Store
import { writable, readable, derived, get } from "svelte/store";
import {
getHeroes,
getHeroById,
deleteHero,
putHero,
postHero
} from "./hero.service";
const initialState = {
heroes: [],
hero: {
_id: "",
firstName: "",
lastName: "",
house: "",
knownAs: ""
},
isLoading: false,
error: ""
};
function createHeroStore() {
const { subscribe, update, set } = writable(initialState);
return {
subscribe,
loadHeroes: async () => {
update(state => (state = { ...state, isLoading: true }));
try {
const res = (await getHeroes()).data;
update(state => (state = { ...state, heroes: res }));
} catch (e) {
alert(e.message);
} finally {
update(state => (state = { ...state, isLoading: false }));
}
},
loadHeroById: async id => {
update(state => (state = { ...state, isLoading: true }));
try {
const res = (await getHeroById(id)).data;
update(state => (state = { ...state, hero: res }));
} catch (e) {
console.log(e.message);
alert(e.message);
}
update(state => (state = { ...state, isLoading: false }));
},
createHero: async newHero => {
update(state => (state = { ...state, isLoading: true }));
try {
const res = (await postHero(newHero)).data;
update(
state =>
(state = { ...state, heroes: [...state.heroes, res] })
);
} catch (e) {
alert(e.message);
} finally {
update(state => (state = { ...state, isLoading: false }));
}
},
/* Optimistic UI update. Updating the UI before sending the request to the web service */
removeHero: async id => {
const confirmation = confirm("You sure you want to delete this?");
if (!confirmation) return;
let previousHeroes;
update(state => {
previousHeroes = state.heroes;
const updatedHeroes = state.heroes.filter(h => h._id !== id);
return (state = { ...state, heroes: updatedHeroes }); // need to return the state only
});
try {
await deleteHero(id);
} catch (e) {
alert(e.message);
update(state => (state = { ...state, heroes: previousHeroes })); // rolling back. =)
}
},
updateHero: async updatedHero => {
update(state => (state = { ...state, isLoading: true }));
try {
await putHero(updatedHero);
update(state => {
const index = state.heroes.findIndex(h => h._id === updatedHero._id);
const copyOfHeroes = state.heroes;
copyOfHeroes[index] = updatedHero;
return (state = {
...state,
heroes: copyOfHeroes
});
});
} catch (e) {
alert(e.message);
} finally {
update(state => (state = { ...state, isLoading: false }));
}
}
};
}
export const heroStore = createHeroStore();
/* computed values */
export const getTotalHeroes = derived(
heroStore,
$heroStore => $heroStore.heroes.length
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment