How to get the name of the method (#action)? - mobx

class UserStore {
#observable rules = {
data:[],
isFeatching: false,
error:false,
};
#observable rooms = {
data:[],
isFeatching: false,
error:false,
};
#observable money = {
data:[],
isFeatching: false,
error:false,
};
#action
async getRules() {
try {
this.rules.isFeatching = true;
const data = await api.getRules();
this.rules.isFeatching = false;
}
}
#action
async getRooms() {
try {
this.rooms.isFeatching = true;
const data = await api.getRooms();
this.rooms.isFeatching = false;
}
}
#action
async getMoney() {
try {
this.money.isFeatching = true;
const data = await api.getMoney();
this.money.isFeatching = false;
}
}
}
Help me please.
Conditions of the problem:
1) I need to get three types of data in one Store.
Task Objective:
1) How to make it so that "isFeatching" is automatically placed?
 
Is there any way to automate?
I had the following thought:
Create a global array (or a class from which I will inherit):
const globalManagerFetching = {UserStore: {
getRules: {isFeatching:false}
getRooms: {isFeatching:false}
getMoney: {isFeatching:false}
}
But how to do it?
  How can I get the name action?
my pseudocode:
#action
async getMoney() {
const methoneName = 'getMoney'; // how to get it automatically?
try {
globalManagerFetching[this.constructor.name][methoneName] = false;
const data = await api.getMoney();
globalManagerFetching[this.constructor.name][methoneName] = true;
}
}
my pseudocode other:
#action
async getMoney() {
try {
setFetching(true);//how to do this?
const data = await api.getMoney();
setFetching(false);//how to do this?
}
}
Tell me please.
Sorry for bad english

If I understand the context of your question correct - you would like to avoid code duplication. I would recommend to solve you this by restructuring your code in such a way:
const { getRules, getRooms, getMoney} = api;
class UserStoreResource {
#observable data = [];
#observable isFetching = false;
#observable error;
constructor(fetchFunction) {
this.fetchData = async ( ) => {
this.isFetching = ture;
await fetchFunction();
this.isFetching = false;
}
}
}
class UserStore {
rules = new UserStoreResource(getRules);
rooms = new UserStoreResource(getRooms);
money = new UserStoreResource(getMoney);
#action
async fetchAllData() {
try {
await Promise.all([
this.rules.fetchData(),
this.rooms.fetchData(),
this.money.fetchData(),
])
}
}
}
If in your components you will use any observable from UserStoreResource - you will get correct rerendering.
Answering your question about getting a function name - its possible by requesting a property arguments.callee.name - but this is deprecated functionality. More here. Most of all - if you need this property - this is an indicator that code requires restructure.

you can get function name like this
const methodName = arguments.callee.name

Related

Custom directive to check the value of two or more fields

I tried my best to write a custom directive in Apollo Server Express to validate two input type fields.
But the code even works but the recording of the mutation already occurs.
I appreciate if anyone can help me fix any error in the code below.
This is just sample code, I need to test the value in two fields at the same time.
const { SchemaDirectiveVisitor } = require('apollo-server');
const { GraphQLScalarType, GraphQLNonNull, defaultFieldResolver } = require('graphql');
class RegexDirective extends SchemaDirectiveVisitor {
visitInputFieldDefinition(field) {
this.wrapType(field);
}
visitFieldDefinition(field) {
this.wrapType(field);
}
wrapType(field) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function (source, args, context, info) {
if (info.operation.operation === 'mutation') {
if (source[field.name] === 'error') {
throw new Error(`Find error: ${field.name}`);
}
}
return await resolve.call(this, source, args, context, info);
};
if (
field.type instanceof GraphQLNonNull
&& field.type.ofType instanceof GraphQLScalarType
) {
field.type = new GraphQLNonNull(
new RegexType(field.type.ofType),
);
} else if (field.type instanceof GraphQLScalarType) {
field.type = new RegexType(field.type);
} else {
// throw new Error(`Not a scalar type: ${field.type}`);
}
}
}
class RegexType extends GraphQLScalarType {
constructor(type) {
super({
name: 'RegexScalar',
serialize(value) {
return type.serialize(value);
},
parseValue(value) {
return type.parseValue(value);
},
parseLiteral(ast) {
const result = type.parseLiteral(ast);
return result;
},
});
}
}
module.exports = RegexDirective;

How can I seperate functions which are basically the same but use different states? Vue2/Vuex

Ive got a problem since i realized that I break the DRY(Dont repeat yourself) rule. So basically I have 2 modules(movies, cinemas) and few methods in them which look the same but use their module' state.
Example: Movies has 'movies' state. Cinemas has 'cinemas' state.
//cinemas.ts
#Mutation
deleteCinemaFromStore(id: string): void {
const cinemaIndex = this.cinemas.findIndex((item) => item.id === id);
if (cinemaIndex >= 0) {
const cinemasCopy = this.cinemas.map((obj) => {
return { ...obj };
});
cinemasCopy.splice(cinemaIndex, 1);
this.cinemas = cinemasCopy;
} else {
throw new Error("Provided id doesn't exist");
}
}
//movies.ts
#Mutation
deleteMovieFromStore(id: string): void {
const movieIndex = this.movies.findIndex((item) => item.id === id);
if (movieIndex >= 0) {
const moviesCopy = this.movies.map((obj) => {
return { ...obj };
});
moviesCopy.splice(movieIndex, 1);
this.movies = moviesCopy;
} else {
throw new Error("Provided id doesn't exist");
}
}
My struggle is: How can I seperate these methods into utils.ts if they have reference to 2 different states?
define another function that take the id, state and store context (this) as parameters :
function delete(id:string,itemsName:string,self:any){
const itemIndex= self[itemsName].findIndex((item) => item.id === id);
if (itemIndex>= 0) {
const itemsCopy = self[itemsName].map((obj) => {
return { ...obj };
});
itemsCopy.splice(itemIndex, 1);
self[itemsName] = itemsCopy;
} else {
throw new Error("Provided id doesn't exist");
}
}
then use it like :
//cities.ts
#Mutation
deleteCityFromStore(id: string): void {
delete(id,'cities',this)
}
//countries.ts
#Mutation
deleteCountryFromStore(id: string): void {
delete(id,'countries',this)
}

Expo-pixi Save stage children on App higher state and retrieve

I'm trying another solution to my problem:
The thing is: im rendering a Sketch component with a background image and sketching over it
onReady = async () => {
const { layoutWidth, layoutHeight, points } = this.state;
this.sketch.graphics = new PIXI.Graphics();
const linesStored = this.props.screenProps.getSketchLines();
if (this.sketch.stage) {
if (layoutWidth && layoutHeight) {
const background = await PIXI.Sprite.fromExpoAsync(this.props.image);
background.width = layoutWidth * scaleR;
background.height = layoutHeight * scaleR;
this.sketch.stage.addChild(background);
this.sketch.renderer._update();
}
if (linesStored) {
for(let i = 0; i < linesStored.length; i++) {
this.sketch.stage.addChild(linesStored[i])
this.sketch.renderer._update();
}
}
}
};
this lineStored variable is returning a data i've saved onChange:
onChangeAsync = async (param) => {
const { uri } = await this.sketch.takeSnapshotAsync();
this.setState({
image: { uri },
showSketch: false,
});
if (this.sketch.stage.children.length > 0) {
this.props.screenProps.storeSketchOnState(this.sketch.stage.children);
}
this.props.callBackOnChange({
image: uri,
changeAction: this.state.onChangeAction,
startSketch: this.startSketch,
undoSketch: this.undoSketch,
});
};
storeSketchOnState saves this.sketch.stage.children; so when i change screen and back to the screen my Sketch component in being rendered, i can retrieve the sketch.stage.children from App.js state and apply to Sketch component to persist the sketching i was doing before
i'm trying to apply the retrieved data like this
if (linesStored) {
for(let i = 0; i < linesStored.length; i++) {
this.sketch.stage.addChild(linesStored[i])
this.sketch.renderer._update();
}
}
```
but it is not working =(

React-Native componentWillRecieveProps rendering issue

In my RN project, I want to achieve this.
// componentWillReceiveProps
componentWillReceiveProps = async (nextProps) => {
let { searchText, peopleTab } = this.props;
let params = {};
if (peopleTab !== nextProps.peopleTab) {
params.peopleTab = nextProps.peopleTab;
}
// here i want to pass nextProps.searchText without a condition with the params like this.
// params.searchText = nextProps.searchText
if (Object.keys(params).length > 0) {
await this.props.fetchUnfollowedPeople(params);
}
}
I want to send nextProps.searchText with params object, if there is a new value. Otherwise I want to send this.props.searchText with the params object.
The above code, if I uncomment
// params.searchText = nextProps.searchText
it gives the infinity loop. How can I achieve this?
Setting the let { searchText, peopleTab } = this.props; in componentWillReceiveProps causes the new value to be pasted
componentWillMount() {
this.searchText = this.props.searchText ;
this.peopleTab = this.props.peopleTab ;
}
componentWillReceiveProps = async (nextProps) => {
const params = [];
if (this.peopleTab !== nextProps.peopleTab) {
params['peopleTab'] = nextProps.peopleTab ;
}
if (Object.keys(params).length > 0) {
await this.props.fetchUnfollowedPeople(params);
}
}

Wit.ai Clear or Reset context

How can I reset or clear the context at the end of my story or when the user wants to restart the process ? I already have a reset function of my own ... Not very effective ! Can you please explain me what I have to do ? Thank you very much
reset({sessionId,context}) {
return new Promise(function(resolve, reject) {
context = null;
return resolve(context);
});
}
And for the session, I do that :
var findOrCreateSession = (fbid) => {
let sessionId;
Object.keys(sessions).forEach(k => {
if (sessions[k].fbid === fbid) {
sessionId = k;
}
});
if (!sessionId) {
console.log("je cree une session car yen a pas");
sessionId = new Date().toISOString();
sessions[sessionId] = {
fbid: fbid,
context: {}
};
}
return sessionId;
};
How can I kill the session at the end of the story and/or kill context and reset the process please !
You could potentially delete the old session and create a new one before the webhook hits the Wit.ai controller.
See the code below for an example:
Webhook POST handler
// Conversation History
let sessionId = WitRequest.getSession(senderId);
if (message.text.toLowerCase() == "break") {
// New Conversation History
// Delete the old session
WitRequest.deleteSession(sessionId);
// Get new Session Id
sessionId = WitRequest.getSession(senderId);
}
let sessionData = WitRequest.getSessionData(sessionId);
wit.runActions(
sessionId,
message.text,
sessionData
)
.then((context) => {
sessionData = context;
})
.catch((error) => {
console.log("Error: " + error);
});
WitRequest Class
static getSession(senderId) {
let sessionId = null;
for (let currentSessionId in sessions) {
if (sessions.hasOwnProperty(currentSessionId)) {
if (sessions[currentSessionId].senderId == senderId) {
sessionId = currentSessionId
}
}
}
if (!sessionId) {
sessionId = new Date().toISOString();
sessions[sessionId] = {
senderId: senderId,
context: {}
}
}
return sessionId;
}
static getSessionData(sessionId) {
return sessions[sessionId].context;
}
static deleteSession(sessionId) {
delete sessions[sessionId];
}
static clearSession(session) {
session.context = {};
}