I have a mock data file that has the content arranged like so:
{
id: 6,
name: 'example',
time: new Date(),
viewed: false,
},
My goal is to be able to count the number of "false" values, and return that count to a Component to be used as content.
I have a file that defines a ModelStore. The beginning of it is like so:
const Model = types
.model('Model', {
id: types.identifierNumber,
name: types.string,
time: types.Date,
viewed: types.boolean,
});
/** @typedef {typeof Model} Model */
/** @typedef {import('mobx-state-tree').Instance<typeof Model>} ModelInstance */
const ModelStoreData = types.model({ Models: types.array(Model) });
You can see the mock data is imported as an array.
I then came up with something like the following:
const ModelStore = types
.compose(
ModelStoreData,
)
.named('ModelStore')
.views((self) => {
/**
* Count number of unviewed models
* @returns {typeof self.Models}
*/
const countUnviewed = (Models) => {
/**
* Numerical urgency levels for sorting
* @enum {number}
*/
const viewedValues = {
[true]: 0,
[false]: 1,
};
/** Returns a numerical value */
const value = Model => viewedValues[Model.viewed];
return Models
// do something with value here to add up
};
return {
get unviewedCount() {
return countUnviewed(self.Models);
},
};
});
/** @typedef {typeof ModelStore} ModelStore */
/** @typedef {import('mobx-state-tree').Instance<typeof ModelStore>} ModelStoreInstance */
export default ModelStore;
but I'm unsure how to proceed from here on how to actually count up the number of "false" values.
I then have this Component that needs that counted value to be inserted:
const myComponent = withRouter(({ history }) => {
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
const toggle = () => {
setIsDropdownOpen(prevDropdownOpen => !prevDropdownOpen);
};
const handleOnClick = () => {
history.push(routes.home.path);
};
return (
<Dropdown isOpen={isDropdownOpen} toggle={toggle}>
<DropdownToggle caret>
Dropdown
</DropdownToggle>
<DropdownMenu right>
<DropdownItem header>viewed items: 2</DropdownItem>
<Button outline onClick={handleOnClick}>go home</Button>
</DropdownMenu>
</Dropdown>
);
});
where "viewed items: 2" is located, substituting the "2" for the counted value.
Any guidance as to how to approach the situation would be appreciated.
You could use the array method filter
to create a new array with every model that has viewed
set to false
and return the length
of that array as unviewedCount
.
const ModelStore = types
.compose(ModelStoreData)
.named("ModelStore")
.views(self => {
return {
get unviewedCount() {
return self.Models.filter(model => !model.viewed).length;
}
};
});
You would then need to create an instance of the ModelStore
and use the observer
function on your component so that your component will re-render if unviewedCount
changes.
const store = ModelStore.create();
const myComponent = withRouter(
observer(({ history }) => {
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
const toggle = () => {
setIsDropdownOpen(prevDropdownOpen => !prevDropdownOpen);
};
const handleOnClick = () => {
history.push(routes.home.path);
};
return (
<Dropdown isOpen={isDropdownOpen} toggle={toggle}>
<DropdownToggle caret>Dropdown</DropdownToggle>
<DropdownMenu right>
<DropdownItem header>
viewed items: {store.unviewedCount}
</DropdownItem>
<Button outline onClick={handleOnClick}>
go home
</Button>
</DropdownMenu>
</Dropdown>
);
})
);