Im using mobx 5.15.7 seeing weird behavior - reactjs

Hello I am use to mobx 4 just getting to mobx 5 and I noticed that the syntax and someways you read observable variables have changed I am trying to log to the console.log the output of some data Im getting from a route, but I am seeing a Proxy and some other stuff. Screenshots are posted below and an explanation would be be greatly appreciated.
Here is what I have some far code wise.
const { team } = this.props.teamStore;
console.log(this.props.teamStore)
const userTeams = !!team ? team : null;
console.log(userTeams)
return (
<div className="text-center mt-40">
<div>Home page again lets get it.</div>
{this.getTeams()}
</div>
);
Here is the weird output I was experincing
[[Handler]]: Object
[[Target]]: Array(3)
[[IsRevoked]]: false

This is normal, MobX 5 uses Proxy under the the hood (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), and this is what it does to your observable data.
You can try to use toJS method on your data if you want regular console output, like that:
import { toJS } from 'mobx';
// ...
console.log(toJS(userTeams))
More here: https://www.mobxjs.com/refguide/tojson.html

Related

Mgt-toolkit get with HTML-attribute data-for doest work with React?

I need to display the values of response, but React doest support the data-for HTML-attribute. When i use the template from https://learn.microsoft.com/en-us/graph/toolkit/components/get I get the error: unexpected variable email. See my implementation below. I can't use {{email.subject}} in this case.
import React, { useState, useEffect, useDebugValue } from 'react';
import { Get } from '#microsoft/mgt-react';
import { useAuth0 } from '#auth0/auth0-react';
function GetMessage() {
const { isAuthenticated } = useAuth0();
const value = <Get></Get>;
console.log(value);
return (
isAuthenticated && (
<mgt-get resource="/me/messages" version="beta" scopes="mail.read" max-pages="2">
<template>
<div class="email" data-for="email in value">
<h3>{{ email.subject }}</h3>
<h4>
<mgt-person person-query="{{email.sender.emailAddress.address}}" view="oneline" person-card="hover"></mgt-person>
</h4>
<div data-if="email.bodyPreview" class="preview" innerHtml>{{email.bodyPreview}}</div>
<div data-else class="preview">email body is empty</div>
</div>
</template>
<template data-type="loading">loading</template>
<template data-type="error">{{ this }}</template>
</mgt-get>
)
)
}
export default GetMessage;
I tried to use the mgt-toolkit examples. The other components works fine.
As per the Doc,React Toolkit do support the data -for HTML-attribute.
In the code you provided above, the error says unable to find the variable mail ,I am wondering you are using authenticating through AuthO,you are using && operation ,might be there is any issue with authentication please confirm once or you can also try to login with React Toolkit , you can also check in the React Toolkit playground, this is working as expected.
Hope this helps,
If you still having the issue , kindly share the screenshot of output as well ,to understand where it fails
Thanks
I am using Auth0 identity provide with Microsoft connection. It works fine with for example and . The response of returns all the emails correctly, but I React doesnt support data-for HTML attribute. The error says: "unexpected token email". See the attachments.
as you can see the tag returns and displays the value
This is the response of . The response is correct, but I cant loop and display for example "bodyPreview."
This shows my implementation
Is there a different approach to display the response? So how can I display the value without data-for attribute?
Thanks for your response and support!

How to access the index of a MaterialUI StepConnector

I am using a Stepper component, and I would like to style the connectors individually based on their index. The need to be able to access the index of the current step from within StepConnector came up in this GitHub issue in February, and a PR was accepted to make this easy with useStepContext. I'm using the current version of MaterialUI, 5.10.4.
However, I'm getting an empty object back instead of the context I'm expecting with the index. This happens with both approaches. The only difference I can see between what I'm doing and the sample code from the GitHub issue is that I'm on 5.10.4 and the sample is using 5.4.0. But perhaps I'm missing something?
Here is my code. The easy way:
import { useStepContext } from "#mui/material/Step/StepContext";
import StepConnector from "#mui/material/StepConnector";
function CIConnector(props) {
const ctx = useStepContext();
console.log("context:", ctx);
return (
<StepConnector />
);
}
The hard way, suggested as a workaround in the original issue before the PR was accepted:
import * as React from "react";
import StepContext from "#mui/material/Step/StepContext";
import StepConnector from "#mui/material/StepConnector";
function CIConnector(props) {
const ctx = React.useContext(StepContext);
console.log("context:", ctx);
return (
<StepConnector />
);
}
In this second version, when I break in the debugger, StepContext is undefined. But if I step into useContext(), it seems to correctly receive the StepContext object. Still, it's returning an empty object.
What am I doing wrong?
I have gotten a minimal test to fail too, so I have opened a bug with MUI.
The problem was the way I was importing the method. This code works on MaterialUI 5.10.17:
import { StepConnector, useStepContext } from "#mui/material/Step";
function CIConnector(props) {
const ctx = useStepContext();
console.log("context:", ctx);
return (
<StepConnector />
);
}

Typescript useState React Hook Destructuring Error (Not Returning Array?)

I'm futzing about with a simple React app for the first time, and looking to set up a simple MVC to connect with an ASP.NET backend, all being done in Visual Studio 2019 (which has caused some headaches with React). However, now that I'm trying to implement models, I'm finding that all of the suggestions for strongly typing the useState hook aren't working for me.
According to a few tutorials like this one or this one, it should be as simple as adding a type in brackets, like const [state, setState] = useState<Type>({}), since it has a generic implementation. Unfortunately, for me, this throws the error "Uncaught TypeError: Invalid attempt to destructure non-iterable instance."
This thread here suggested that switching from an array to an object by changing the [] to {}, however that simply made the two parameters I passed be undefined, so I had no state or way to update said state.
I went down the path of reading until I had a brief understanding of array destructuring, so I understand that the idea is to pass an array with two constants that will be assigned in-order the elements of the array returned by the useState hook. So, I tried manually destructuring the array, setting a constant useState[0] and useState[1] separately. When I tried this for an untyped hook, it worked as expected. When I tried this for the typed hook, I got some errors about there not being elements, and upon printing out the object, found not an array like the untyped hook, but a boolean. It seems that a typed useState is returning the value "false" instead of an array.
At this point, my best guess is that I have some dependencies that don't implement the typed useState, but I'm really hitting a stone wall on troubleshooting. Anyone have some idea on what I'm doing wrong?
Edit: The testing file I have set-up -
import React, { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import { Product } from '../Models/Product';
const Account = () => {
//Works as-intended
const test = useState(5);
//Returns false when logged
const test2 = useState<Product>({
"ProductID": "p#corn", "Description": "Delicious corn", "ImageLink": "https://testlink.com", "Name": "Corn", "Price": "2.99", "Category": "Food"
});
//What should work, to my understanding, however this makes the route crash when it's navigated to because of the "Inavlid attempt to destructure non-iterable instance
const [test3, setTest] = useState<Product>({});
function clickHandler() {
console.log(test)
}
function clickHandler2() {
console.log(test2)
}
return (
<div className='wrapper'>
<button onClick={clickHandler}>Test</button>
<button onClick={clickHandler2}>Test2</button>
</div>
)
}
export default Account;
The Product model -
export interface Product {
ProductID: string;
Description: string;
ImageLink: string;
Name: string;
Price: string;
Category: string;
}
Here's a CodeSandbox with an example somewhat related to your case, which demonstrates how useState is meant to work on everyone else's machine.
As you will see from testing it and messing with the example I shared, useState with a generic type specified should be fine and dandy and behave just as you expect.
That underlines that there's something about your local machine or project environment which is special to you.
import React, { useCallback, useState } from "react";
import "./styles.css";
interface Product {
Name: string;
Price: number;
}
const productA = {
Name: "Corn",
Price: 2.99
};
const productB = {
Name: "Frozen Orange Juice",
Price: 10_000
};
export default function Show() {
const [product, setProduct] = useState<Product>(productA);
const toggleProduct = () =>
setProduct(product === productA ? productB : productA);
return (
<div className="App" onClick={toggleProduct}>
<h1>{product.Name}</h1>
<h2>{product.Price}</h2>
</div>
);
}
Since you asked about how to get the best responses...
Ideally when posting try to create a problem case which other people can see failing. If you attempt to do this (e.g. using a CodeSandbox) but it works fine there, then it's a matter of working on cleaning up your own local environment until you figure out what is unique about your setup which makes code break for you but no-one else.
Ideally if you can't create it within a single page repro (sandbox), because it's something to do with your project structure, create a runnable reproduction by sharing the actual project structure and its code and configuration publically on github so people can recreate your problem by checking it out and building/running it. That way they will soon be able to track down what's distinctive about your project.
Often this process of creating a repro will help you figure out the problem anyway - e.g. you start with a vanilla create-react-app typescript skeleton from https://create-react-app.dev/docs/adding-typescript/ to populate a blank github repo and your problem case suddenly starts working there - now you have a basis for bisecting your problem by adding your project's special features to the simple repro until it breaks.

How to handle validation for Redux-Form FieldArrays with Immutable.js?

I'm currently using redux-form/immutable, Wizard-Form, and FieldArrays to create a multi-step form for a project. I'm basically getting stuck on how to validate the field arrays with immutable.js.
I've followed the following example: https://redux-form.com/8.1.0/examples/immutable/ to setup validation in validate.js file with immutable but I also had to follow the following example https://redux-form.com/8.1.0/examples/fieldarrays/ to figure out how to do validation for FieldArrays.
By following both examples I came up with the following:
if (values.get('customTrips')) {
const customTripArrayErrors = [];
values.get('customTrips').forEach((member, memberIndex) => {
const customTripMemberErrors = {};
if (!member.get('from_location_address1') {
}
}
}
When I try the above code I get the following error:
Uncaught TypeError: Cannot read property 'get' of undefined
I just need help figuring out how to access FieldArray member values in validate.js.
Any help would be greatly appreciated! Thanks!
My idea was right but I missed an important step when pushing to a Redux-Form FieldArray. You need to make sure when you push, you are creating a new Map so that you can access the values with get. If you don't create a new Map and you console.log(member), you will see that it is undefined. Hope this helps as this was not written in the Redux-Form docs!
import { Map } from 'immutable';
<FlatButton
type="button"
onClick={() => fields.push(new Map())}
backgroundColor={Color.primary}
hoverColor={Color.primaryDarkened}
className="left"
label="Add a Local Trip"
/>

Firebase and React with react-snapshot (pre-rendering)

I"m new to firebase, just wrote a little simple test react component before putting all of data on to firebase, but unfortunately I couldn't make it work with Server Side Pre-Rendering. It's very important to make it SEO friendly for me, and I've searching around on the internet for the solution, but still couldn't really figure it out. please help me out with this. thanks very much in advance.
The simple code below will only generate the initial state with React-Snapshot, when I open the the page it will show initial state and then update to newer state. But I need to make the initial state object fetching data directly from Firebase and generate static html with React-Snapshot.
class FirebaseTestingComponent extends Component {
constructor(){
super();
this.state = {
speed: 10
};
}
componentWillMount(){
const rootRef = firebase.database().ref().child('react');
const speedRef = rootRef.child('speed');
speedRef.on('value', snap => {
this.setState({
speed: snap.val()
});
});
}
render(){
return (
<div>
<h1>{this.state.speed}</h1>
</div>
);
}
}
By SEO friendly I assume you want static content instead of dynamic (not an expert on SEO) but firebase runs asynchronously especially when you use .on() that's like websocket, doesn't matter if you do willmount or didmount this case.
My humble suggestion for the design is to fetch from firebase in your server before render the page (firebase support java and node for sure, not sure about the rest), and set initial state with that value you fetched, that will guarantee your initial state is from firebase. From that you can still use that .on() for later value coming in.

Resources