I am trying to clear localstorage with a button and an addEventListener. But its not working, and I cant figure out why. Thanks.
const clearStorage = document.querySelector(".clear-button");
clearStorage.addEventListener("click", (function(){
localStorage.clear();
}));
};
This code gets imported to the script below:
import { getFavourites } from "./utils/getFavs.js";
import createMenu from "./components/createMenu.js";
import displayMessage from "./components/displayMessage.js";
import { clearFavList } from "./components/clearFavList.js"
createMenu();
getFavourites();
const favouriteList = getFavourites();
const articlesContainer = document.querySelector(".favourites-container");
if(!favouriteList.length) {
displayMessage("error", "You don't have any saved favourites yet.", ".favourites-container");
}
favouriteList.forEach((favourite) => {
articlesContainer.innerHTML += `<div class="article">
<div class="article-content-text">
<h2 class="article-title fav-wrapper-text">Title: ${favourite.title}</h2>
</div>
<div>
<i class="fas fa-heart favButton"></i>
</div>
</div>`;
});
clearFavList(favouriteList);
This code, from a React auth component, have all the basic functions to handle storage.
// you can create multiple storage stores
const LOCAL_STORAGE_STORE = 'storage_sample';
export const getHasLocalStorageAuth = () => {
// check local storage
const localStorage = __getLocalStorage(LOCAL_STORAGE_STORE);
return { status: !!localStorage, data: localStorage.auth };
};
export const clearLocalStorageAuth = () => {
__clearLocalStorage(LOCAL_STORAGE_STORE);
return;
};
export const setLocalStorageAuth = (newLocalStorage: any) => {
__setLocalStorage(LOCAL_STORAGE_STORE, newLocalStorage);
return;
};
// setting data to localstorage
export function __setLocalStorage(
localStorageName: string,
localStorageValue: any,
isJson = true
) {
if (isJson) {
localStorage.setItem(localStorageName, JSON.stringify(localStorageValue));
} else {
localStorage.setItem(localStorageName, localStorageValue);
}
}
// getting data from localstorage
export function __getLocalStorage(localStorageName: string): any {
let localStorageValue: any;
if (localStorage.getItem(localStorageName) !== null) {
localStorageValue = localStorage.getItem(localStorageName);
} else {
localStorageValue = false;
}
return JSON.parse(localStorageValue);
}
// clear data from localstorage
export function __clearLocalStorage(localStorageName: string | null) {
localStorage.clear();
}
Related
I'm trying to fetch all objects from the favorites array and set the checkbox to checked
I've checked online and tried using the localStorage for that yet nothing works and the values aren't saved after refreshing.
Would appreciate any help!
Selected Book Component :
import React, { useEffect, useState } from 'react';
import { bookService } from '../service/book.service';
export const SelectedBook = ({ selectedBook, setFavorites, favorites, removeFavorite }) => {
const onHandleFavorite = (book, e) => {
if (e.currentTarget.checked) {
setFavorites([...favorites, book]);
bookService.addFavorite(book);
} else {
removeFavorite(book);
}
};
const isFavorite = () => {
if (!favorites.includes(selectedBook)) {
return false;
} else {
return true;
}
};
return (
<div className='selected-book-container'>
<input type='checkbox' checked={isFavorite()} onChange={(e) => onHandleFavorite(selectedBook, e)} />
<div className='title'>{selectedBook?.title}</div>
</div>
);
};
Book Page component :
import React, { useEffect, useState } from 'react';
import { bookService } from '../service/book.service.js';
import { BookList } from '../cmps/BookList';
import { SelectedBook } from '../cmps/SelectedBook.jsx';
import { utilService } from '../service/util.service';
export const BookPage = () => {
const [books, setBooks] = useState([]);
const [favorites, setFavorites] = useState([]);
const [index, setIndex] = useState(0);
const [selectedBook, setSelectedBook] = useState();
useEffect(() => {
bookService.favoriteQuery().then((res) => {
setFavorites(res);
});
}, []);
useEffect(() => {
bookService.query().then((res) => {
setBooks(res);
setSelectedBook(res[0]);
});
}, []);
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '37') {
if (index === 0) return;
setIndex(index - 1);
} else if (e.keyCode == '39') {
if (index >= books.length - 1) return;
setIndex(index + 1);
}
}
useEffect(() => {
setSelectedBook(books[index]);
}, [index]);
const removeFavorite = (book) => {
setFavorites(favorites.filter((favorite) => favorite.id !== book.id));
bookService.removeFavorite(selectedBook);
};
return (
<div>
<div className='main-container main-layout'>
<div className='second'>
<SelectedBook
selectedBook={selectedBook}
setFavorites={setFavorites}
favorites={favorites}
removeFavorite={removeFavorite}
/>
<BookList books={favorites} removeFavorite={removeFavorite} />
</div>
</div>
<div className='footer-container'>
<section className='footer'>Footer</section>
</div>
</div>
);
};
Service :
async function favoriteQuery() {
try {
let favorites = await _loadeFavoriteFromStorage();
if (!favorites) return (favorites = []);
return favorites;
} catch (err) {
console.log('cannot load favorites', err);
}
}
function _loadeFavoriteFromStorage() {
return storageService.loadFromStorage(STORAGE_FAVORITE_KEY);
}
Storage Service :
export const storageService = {
loadFromStorage,
saveToStorage
}
function saveToStorage(key, val) {
localStorage.setItem(key, JSON.stringify(val))
}
function loadFromStorage(key) {
var val = localStorage.getItem(key)
return JSON.parse(val)
}
thanks for any kind of help
You're not updating localstorage each time that checked is being changed. You're calling setFavorites with a new set of favorites but this is just changing state. I would suggest creating a function within the book page component which does
function changeFavorite(book, checked){
saveToStorage(book?, checked)
rerender()
}
and having rerender set the state of favorites to whatever is in localstorage to ensure that you have a single source of truth which is found in localstorage and that you change that and not anything else
I'll just add
if (!favorites.includes(selectedBook)) {
return false;
} else {
return true;
}
};
Could really look like
const isFavorite () => favorites.includes(selectedBook)
I also didn't quite understand how you're doing about storing the books in object storage. You should probably have an id of some sorts which you use to save favorite information with
I am building a sample recipe app named : Forkify using Javascript,NPM,Babel and Webpack in which i am using custom API
API URL : forkify-api.herokuapp.com
TO SEARCH RESULT
Returns a list of recipes for a specific query
Path: https://forkify-api.herokuapp.com/api/search
Example URL: https://forkify-api.herokuapp.com/api/search?q=pizza
GET
Returns the details about a specific recipe
Path: https://forkify-api.herokuapp.com/api/get
Example URL: https://forkify-api.herokuapp.com/api/get?rId=47746
When i run project in command line using command npm start run and when i input query pizza in search box, i get the following error ( image attached )
Below are the code files :
index.js
/*
Global state of the app
- search object
- current recipe object
- shopping list object
- liked recipe
*/
import Search from "./models/Search";
import Recipe from "./models/Recipe";
import * as searchView from "./views/searchView";
import { elements, renderLoader, clearLoader } from "./views/base";
const state = {};
/* SEARCH CONTROLLER */
const controlSearch = async () => {
// 1. Get query from the view.
const query = searchView.getInput(); //TODO
// console.log(query);
if (query) {
// 2. New search object and add it to state.
state.search = new Search(query);
// 3. Prepare UI for results.
searchView.clearinput();
searchView.clearResults();
renderLoader(elements.searchRes);
// 4. Search for recipes.
await state.search.getResults();
// 5. Render results on UI.
clearLoader();
searchView.renderResults(state.search.result);
}
}
elements.searchForm.addEventListener("submit", e => {
e.preventDefault();
controlSearch();
});
elements.searchResPages.addEventListener("click",e=>{
const btn=e.target.closest(".btn-inline");
if (btn) {
const goToPage=parseInt(btn.dataset.goto,10);
searchView.clearResults();
searchView.renderResults(state.search.result,goToPage);
}
});
Search.js
import axios from "axios";
// import {proxy} from "../config";
export default class Search{
constructor(query){
this.query=query;
}
async getResults() {
try{
const res = axios(`https://forkify-api.herokuapp.com/api/search?q=${this.query}`);
this.result = res.data.recipes;
// console.log(this.result);
}
catch(error){
alert(error);
}
};
}
searchView.js
import { elements } from "./base";
export const getInput = () => elements.searchInput.value;
export const clearinput = () => {
elements.searchInput.value = "";
};
export const clearResults = () => {
elements.searchResList.innerHTML = "";
elements.searchResPages.innerHTML = "";
};
/*
"pasta with tomato and spinach"
acc:0/acc+curr.length=5 /newTitle =['pasta']
acc:5/acc+curr.length=9 /newTitle =['pasta','with']
acc:9/acc+curr.length=15 /newTitle =['pasta','with','tomato']
acc:15/acc+curr.length=18 /newTitle =['pasta','with','tomato']
acc:18/acc+curr.length=25 /newTitle =['pasta','with','tomato']
*/
const limitRecipeTitle = (title, limit = 17) => {
const newTitle = [];
if (title.length > limit) {
title.split(" ").reduce((acc, curr) => {
if (acc + curr.length <= limit) {
newTitle.push(curr);
}
return acc + curr.length;
}, 0);
// return the results
return `${newTitle.join(' ')}...`;
}
return title;
};
const renderRecipe = recipe => {
const markup = `
<li>
<a class="results__link" href="#${recipe.recipe_id}">
<figure class="results__fig">
<img src="${recipe.image_url}" alt="${recipe.title}">
</figure>
<div class="results__data">
<h4 class="results__name">${limitRecipeTitle(recipe.title)}</h4>
<p class="results__author">${recipe.publisher}</p>
</div>
</a>
</li>
`;
elements.searchResList.insertAdjacentHTML("beforeend", markup);
};
// type: "prev" or "next"
const createButton = (page, type) => `
<button class="btn-inline results__btn--${type}" data-goto=${type === "prev" ? page - 1 : page + 1}>
<span>Page ${ type === "prev" ? page - 1 : page + 1}</span>
<svg class="search__icon">
<use href="img/icons.svg#icon-triangle-${ type === "prev" ? "left" : "right"}"></use>
</svg>
</button>
`
const renderButtons = (page, numResults, resPerPage) => {
const pages = Math.ceil(numResults / resPerPage);
let button;
if (page === 1 && pages > 1) {
// Only button to go to next page.
button = createButton(page, "next");
}
else if (page < pages) {
// Both buttons
button = `
${createButton(page, "prev")}
${createButton(page, "next")}
`;
}
else if (page === pages && pages > 1) {
// Only button to go to previous page.
button = createButton(page, "prev");
}
elements.searchResPages.insertAdjacentHTML("afterbegin", button);
}
export const renderResults = (recipes, page = 1, resPerPage = 10) => {
// render results of current page
const start = (page - 1) * resPerPage;
const end = page * resPerPage;
// recipes.slice(start,end).forEach(renderRecipe);
recipes.slice(start, end).forEach(renderRecipe);
// render pagination buttons
renderButtons(page, recipes.length, resPerPage);
};
Recipe.js
import axios from "axios";
// import {key} from "../config";
export default class Recipe{
constructor (id){
this.id=id;
}
async getRecipe(){
try {
const res=await axios(`https://forkify-api.herokuapp.com/api/get?rId=${this.query}`);
console.log(res);
} catch (error) {
console.log(error);
}
}
};
base.js
export const elements = {
searchForm: document.querySelector(".search"),
searchInput: document.querySelector(".search__field"),
searchRes: document.querySelector(".results"),
searchResList: document.querySelector(".results__list"),
searchResPages:document.querySelector(".results__pages")
};
export const elementStrings = {
loader: "loader"
};
export const renderLoader = parent => {
const loader = `
<div class="${elementStrings.loader}">
<svg>
<use href="img/icons.svg#icon-cw">
</use>
</svg>
</div>
`;
parent.insertAdjacentHTML("afterbegin", loader);
};
export const clearLoader = () => {
const loader = document.querySelector(`.${elementStrings.loader}`);
if (loader) loader.parentElement.removeChild(loader);
};
any solution please ?
You are missing the await keyword from your axios call in Search.js:
const res = await axios(`https://forkify-api.herokuapp.com/api/search?q=${this.query}`);
this.result = res.data.recipes;
This is why you are seeing the error:
TypeError: Cannot read property 'recipes' of undefined
Then undefined gets passed to renderResults, which is why you see the console error:
TypeError: Cannot read property 'slice' of undefined
You can default the recipes parameter to an empty array to ensure that slice can be called even if undefined is passed:
export const renderResults = (recipes = [], page = 1, resPerPage = 10) => {
// ...
}
I'm using React/Redux in this code and I'm trying to pass the correct prop by action. My intention is to change converter name on click modal button. But when I debbug, console server shows me the same action with no alteration clicking on confirm button.
My action in file actions:
export const saveOrUpdateConverter = converter => {
return {
converter,
type: CONVERTER.SAVE_OR_UPDATE_CONVERTER
};
};
The function I'm using to do that:
export const saveOrUpdateConverter = (converter, type) => {
const url = `${BASE_URL}/SaveOrUpdateConverter`;
let converterWithoutId = {
...converter,
Id: 0
};
return makeRequest(
{
method: "post",
url,
data: type === "edit" ? converter : converterWithoutId
},
(data, dispatch) => {
// if we are adding a new converter, we need to remove it from newConverters
if (type === "add") {
dispatch(actions.removeFromNewConverters(converter));
}
dispatch(actions.saveOrUpdateConverter(data));
},
true
);
};
The file where I'm calling the function
const handleSaveUpdateConverter = async () => {
let type = "edit";
return await props.saveOrUpdateConverter(converter, type);
};
Component receiving function by prop:
<AddOrEditConverterModal
converter={converter}
show={showEditConverterModal}
onCloseModal={() => setShowEditConverterModal(false)}
saveOrUpdateConverter={(converter, propsType) =>
handleSaveUpdateConverter(converter, propsType)
}
type={"edit"}
/>
I finally call the props saveOrUpdateConverter in other file:
const updateConverter = async () => {
if (converter.IntervalToSavePayload < 5) {
props.requestError(
true,
props.intl.formatMessage({
id: "modal.base.converter.interval.save.pyload.error"
})
);
return;
}
await props.saveOrUpdateConverter(converter, props.type);
debugger
props.onCloseModal();
};
Connect function to use saveOrUpdateConverter :
import { connect } from "react-redux";
import { saveOrUpdateConverter } from "Features/Devices/Converters/actions";
import ConverterPage from "./ConverterPage";
const mapStateToProps = state => ({
activeConverters: state.converter.activeConverters,
activeInstruments: state.instrument.activeInstruments
});
export default connect(mapStateToProps, {saveOrUpdateConverter})(ConverterPage);
I am simply looking to save and restore a search term(form data) when a page is refreshed/reloaded. I have tried several solutions to no avail.
Flow: A user submits a search term and is taken to Spotify to retrieve an accessToken, if it is not already available. The initial page is refreshed once the accessToken is retrieved, but the search must be re-entered. This is not good UX.
I concluded that Web Storage was they way to go, of course it is not the only route. I am not sure if this is something that should be relegated to Lifecycle methods: componentDidMount() & componentDidUpdate(). Perhaps that is overkill? In any event, I attempted to employ both localStorage and sessionStorage. My implementation is obviously off as I am not getting the expected result. React dev tools displays the state of the SearchBar term, but it is not being saved. Also of note is the following: React dev tools shows that the onSubmit event handler is registering as bound () {} instead of the expected bound handleInitialSearchTerm() {}. The console also shows that there are no errors.
No third-party libraries please.
SearchBar.js
import React from 'react';
import "./SearchBar.css";
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.state = {
term: this.handleInitialSearchTerm
};
this.search = this.search.bind(this);
this.handleInitialSearchTerm = this.handleInitialSearchTerm.bind(this);
this.setSearchTerm = this.setSearchTerm.bind(this);
this.handleSearchOnEnter = this.handleSearchOnEnter.bind(this);
this.handleTermChange = this.handleTermChange.bind(this);
}
handleInitialSearchTerm = (event) => {
if (typeof (Storage) !== "undefined") {
if (localStorage.term) {
return localStorage.term
} else {
return this.setSearchTerm(String(window.localStorage.getItem("term") || ""));
}
}
};
setSearchTerm = (term) => {
localStorage.setItem("term", term);
this.setState({ term: term });
}
search() {
this.props.onSearch(this.state.term);
}
handleSearchOnEnter(event) {
if (event.keyCode === 13) {
event.preventDefault();
this.search();
}
}
handleTermChange(event) {
this.setState({
term: event.target.value
});
}
render() {
return (
<div className="SearchBar">
<input
placeholder="Enter A Song, Album, or Artist"
onChange={this.handleTermChange}
onKeyDown={this.handleSearchOnEnter}
onSubmit={this.handleInitialSearchTerm}
/>
<button className="SearchButton" onClick={this.search}>
SEARCH
</button>
</div>
);
}
}
export default SearchBar;
Motify.js
let accessToken;
const clientId = "SpotifyCredentialsHere";
const redirectUri = "http://localhost:3000/";
const CORS = "https://cors-anywhere.herokuapp.com/"; // Bypasses CORS restriction
const Motify = {
getAccessToken() {
if (accessToken) {
return accessToken;
}
// if accessToken does not exist check for a match
const windowURL = window.location.href;
const accessTokenMatch = windowURL.match(/access_token=([^&]*)/);
const expiresInMatch = windowURL.match(/expires_in=([^&]*)/);
if (accessTokenMatch && expiresInMatch) {
accessToken = accessTokenMatch[1]; //[0] returns the param and token
const expiresIn = Number(expiresInMatch[1]);
window.setTimeout(() => accessToken = "", expiresIn * 1000);
// This clears the parameters, allowing us to grab a new access token when it expires.
window.history.pushState("Access Token", null, "/");
return accessToken;
} else {
const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;
window.location = accessUrl;
}
},
search(term) {
const accessToken = Motify.getAccessToken();
const url = `${CORS}https://api.spotify.com/v1/search?type=track&q=${term}`;
return fetch(url, { headers: { Authorization: `Bearer ${accessToken}` }
}).then(response => response.json()
).then(jsonResponse => {
if (!jsonResponse.tracks) {
return [];
}
return jsonResponse.tracks.items.map(track => ({
id: track.id,
name: track.name,
artist: track.artists[0].name,
album: track.album.name,
uri: track.uri,
preview_url: track.preview_url
}));
})
}
...
Please check the code I have added.
Changes I did are below:
1)
this.state = {
term: JSON.parse(localStorage.getItem('term')) || '';
};
setSearchTerm = (term) => {
this.setState({
term: term
},
() => {
localStorage.setItem('term', JSON.stringify(this.state.term)));
}
import React from 'react';
import "./SearchBar.css";
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.state = {
term: JSON.parse(localStorage.getItem('term')) || '';
};
this.search = this.search.bind(this);
this.handleInitialSearchTerm = this.handleInitialSearchTerm.bind(this);
this.setSearchTerm = this.setSearchTerm.bind(this);
this.handleSearchOnEnter = this.handleSearchOnEnter.bind(this);
this.handleTermChange = this.handleTermChange.bind(this);
}
handleInitialSearchTerm = (event) => {
if (typeof(Storage) !== "undefined") {
if (localStorage.term) {
return localStorage.term
} else {
return this.setSearchTerm(String(window.localStorage.getItem("term") || ""));
}
}
};
setSearchTerm = (term) => {
this.setState({
term: term
},
() => {
localStorage.setItem('term', JSON.stringify(this.state.term)));
}
search() {
this.props.onSearch(this.state.term);
}
handleSearchOnEnter(event) {
if (event.keyCode === 13) {
event.preventDefault();
this.search();
}
}
handleTermChange(event) {
this.setState({
term: event.target.value
});
}
render() {
return ( <
div className = "SearchBar" >
<
input placeholder = "Enter A Song, Album, or Artist"
onChange = {
this.handleTermChange
}
onKeyDown = {
this.handleSearchOnEnter
}
onSubmit = {
this.handleInitialSearchTerm
}
/> <
button className = "SearchButton"
onClick = {
this.search
} >
SEARCH <
/button> <
/div>
);
}
}
export default SearchBar;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
If it is in hooks i would have done like below:
import React, {
useEffect,
useState,
useRef,
} from 'react';
function App() {
const [value, setValue] = useState(() => {
if (localStorage.getItem('prevCount') === null) {
return 0;
} else {
return localStorage.getItem('prevCount');
}
});
const countRef = useRef();
useEffect(() => {
countRef.current = value;
if (countRef.current) {
localStorage.setItem('prevCount', countRef.current);
} else {
localStorage.setItem('prevCount', 0);
}
});
const handleIncrement = () => {
setValue((value) => +value + 1);
};
const handleDecrement = () => {
if (value === 0) {
return;
} else {
setValue((value) => value - 1);
}
};
return (
<div className="card">
<label className="counterLabel">Simple Counter</label>
<button
className="button"
onClick={handleIncrement}
>
Increment
</button>
<span className="count">{value}</span>
<button
className="button"
onClick={handleDecrement}
>
Decrement
</button>
</div>
);
}
export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
So what the above code is doing is that when we inititalize the state value we first check the localStorage , if "term" has value in localStorage we will use that value or else an empty string is initialized.
Using callback of setState inside the method setSearchTerm we set the term value immediately
Try the useLocalStorage hook to save search client side.
// useLocalStorage Hook to persist values client side
function useLocalStorage(key, initialValue) {
// State to store our value
// Pass initial state function to useState so logic is only executed once
const [storedValue, setStoredValue] = useState(() => {
if (typeof window === "undefined") {
return initialValue;
}
try {
// Get from local storage by key
const item = window.localStorage.getItem(key);
// Parse stored json or if none return initialValue
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// If error also return initialValue
console.log(error);
return initialValue;
}
});
// Return a wrapped version of useState's setter function that ...
// ... persists the new value to localStorage.
const setValue = (value) => {
try {
// Allow value to be a function so we have same API as useState
const valueToStore =
value instanceof Function ? value(storedValue) : value;
// Save state
setStoredValue(valueToStore);
// Save to local storage
if (typeof window !== "undefined") {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
} catch (error) {
// A more advanced implementation would handle the error case
console.log(error);
}
};
return [storedValue, setValue];
}
credit: Brandon Baars
Im wondering how I can call a method from outside of a React Functional Component. I wrote the function GetUsedLockers() which gets all the used lockers and returns amount. Now I want to call this function from another another component (OrgLocker.tsx) and display the data from the getUsedLockers() function there.
OrgLockerTables.tsx
const OrgLockerTables: React.FC = () => {
const lockerCall = 'lockers';
const [lockerData, setLockerData] = useState({
id: 0,
guid: "",
is_currently_claimable: false
}[""]);
useEffect(() => {
componentConsole().then((res) => {
setLockerData(res);
})
// eslint-disable-next-line
}, []);
if (!lockerData) return (<div>Loading...</div>);
//function to get all used lockers
function getUsedLockers() {
let amount = 0;
for (let i = 0; i < lockerData.length; i++) {
if (!lockerData.is_currently_claimable) {
amount++;
}
}
console.log('log from getusedlockers, amount: ', amount)
return (amount)
}
// function to get JSON data from the API
function componentConsole(): Promise<any> {
return new Promise<any>((resolve, reject) => {
http.getRequest('/' + lockerCall).then((res) => {
let data = res.data.data;
console.log('data:', data);
resolve(res.data.data);
}).catch((error) => {
console.log(error);
reject();
});
})
}
}
OrgLocker.tsx
import OrgLockerTables from '../tables/orgLockerTables';
const OrgLockers: React.FC = () => {
let lockerTable = new OrgLockerTables();
return (
<div className="main-div-org">
<p>Used</p>
<p>{lockerTable.getUsedLockers()}</p>
</div>
);
}
export default OrgLockers;
When trying to make a call to OrgLockerTables and storing it in the lockerTable let it gives the following error:
Expected 1-2 arguments, but got 0.ts(2554)
Any help would be greatly appreciated!
I've restructured everything making it more understandable, I hope you don't mind according to what I think you want the comment above.
locker-model.ts - The type for the particular data being called back is found
export type Locker = {
id: number;
guid: string;
isCurrentlyClaimable: boolean;
}
locker-business.ts - Where all the business logic is carried out, from the call for data to the calculation based on it
import { Locker } from "./locker-models";
const lockerCall = 'lockers';
const mockedData: Locker[] = [{
id: 0,
guid: "sample",
isCurrentlyClaimable: false,
},
{
id: 1,
guid: "sample2",
isCurrentlyClaimable: true,
},
{
id: 2,
guid: "sample3",
isCurrentlyClaimable: true,
}]
// Mocked function from your backend (componentConsole where you use lockerCall variable)
export const getLockersData = (): Promise<Locker[]> => Promise.resolve(mockedData);
export const getAmount = (lockers: Locker[]): number => {
let amount = 0;
!!lockers ?
lockers.filter(({isCurrentlyClaimable}) => { if(isCurrentlyClaimable) amount++ })
: 0;
return amount;
};
index.tsx - Here are both components that make the call to get the data and render the result you're looking for
import React, { Component } from 'react';
import { Locker } from './locker-models';
import { getLockersData, getAmount } from './locker-business';
import './style.css';
type OrgLockersProps = {
amount: number;
}
const OrgLockers: React.FC<OrgLockersProps> = ({ amount }) => {
return (
<div className="main-div-org">
<p>Lockers used:</p>
<p>{amount}</p>
</div>
);
}
type OrgLockerTableProps = {};
const OrgLockerTable : React.FC<OrgLockerTableProps> = props => {
const [lockerData, setLockerData] = React.useState<Locker[]>([]);
React.useEffect(() => {
getLockersData().then(response => setLockerData(response));
}, []);
const amount = getAmount(lockerData);
return (
<div>
<OrgLockers amount={amount} />
</div>
);
};
You can see the example here
You can create new .js file like Helpers.js and define export function with parameter it like that
export function getUsedLockers(lockerData) {
let amount = 0;
//Check your loop it can be like that
for (let i = 0; i < lockerData.length; i++) {
if (!lockerData[i].is_currently_claimable) {
amount++;
}
}
console.log('log from getusedlockers, amount: ', amount)
return (amount)
}
Then import it where do you want to use.
import {getUsedLockers} from "../Helpers";
And use it like that:
const amount = getUsedLockers(data);