I have a react function returning a promise from axios, and I need to encode an equation type string is being passed to it.
const { equation } = this.state;
axios.post(`${this.state.rootUrl}/integrate`, { equation }).then(some other code)
I want to encode the string equation before passing it to the API for a query.
I have tried the following but it didn't work.
axios.post(`${this.state.rootUrl}/integrate`, { encodeURIComponent(equation) })
I also tried this:
const { equation } = this.state;
const { test } = encodeURIComponent(equation);
axios.post(`${this.state.rootUrl}/integrate`, { test }).then(some other code)
This also didn't work.
Here's the full code of the function where I'm trying use this:
handleSubmit = (e) => {
e.preventDefault();
const { equation } = this.state;
// const { test } = encodeURIComponent(equation);
axios.post(`${this.state.rootUrl}/integrate`, { equation })
.then((response) => {
const data = response.data;
this.setState({ data: data });
console.log(equation);
if (data != null) {
this.setState({input: data.response[0]});
}
}
}
In your original example, you're using the shorthand syntax for setting object properties - the following two lines of code are equivalent:
{ equation }
{ equation: equation }
Your second two examples don't do the same thing! In example two, you're trying to use the shorthand with a method call, which won't work. In example three, you're trying to destructure the return value of encodeURIComponent(equation), which also won't work (it returns a string).
Fawaz's first example almost works, but there's a subtle difference in behavior - because they've named the variable test, the key of the object being passed to Axios will also be test. Remember, these are equivalent:
{ test }
{ test: test }
Presumably, your API is expecting something called equation, not test, so this won't work.
To get the right behavior, you should make sure the object you're passing has the right key:
const test = encodeURIComponent(equation);
axios.post(`${this.state.rootUrl}/integrate`, { equation: test })
// or
axios.post(`${this.state.rootUrl}/integrate`, { equation: encodeURIComponent(equation) })
There seems an issue in using the shorthand. Try like this :
const test = encodeURIComponent(equation); // no braces here
axios.post(`${this.state.rootUrl}/integrate`, { test }).then(some other code)
or
axios.post(`${this.state.rootUrl}/integrate`, { test: encodeURIComponent(equation) })
Related
I have the following:
export const ObjC = Codec.struct({
name: Codec.string,
value: Codec.number,
})
export type ObjType = Codec.TypeOf<typeof ObjC>
I want a function for decoding this object and returning an Error (not DecoderError). Similar to:
import { fold } from 'fp-ts/lib/Either'
import { pipe } from 'fp-ts/lib/function'
const decodeObj = async (str: string): Promise<Either<Error, ObjType>> => {
return pipe(
ObjC.decode(str),
fold(err => toError(err), m => m), // This doesn't do want I want
)
}
How can I return the right types for this function in an idiomatic way?
Just going off of the return type you've listed, it sounds to me like you want to perform a transformation to the left value when the thing is Left and leave the code unchanged when the value is Right. In that case the mapLeft helper function is exactly what you're looking for.
This can be achieved by saying:
import { mapLeft } from 'fp-ts/lib/Either';
// -- rest of your code --
const decodeObj = async (str: string): Promise<Either<Error, ObjType>> => {
return pipe(
objCodec.decode(str),
mapLeft(toError),
);
};
However, I have some questions. For one the code as written will never succeed to parse because the input string will never match an object. I'm guessing there are other piece of logic you've omitted, but as it stands the code looks a bit wrong.
I'm currently taking an online course to learn React and I'm confused as to when I should be using { vs (.
I have 3 files:
App.js
const App = () => {
card-list.component.jsx
const CardList = ({ monsters }) => (
card.component.jsx
const Card = ({ monster }) => {
This is the code that currently works. Notice that on the second code the last character used is (. I thought of changing it to { to make it consistent with the other files but somehow the card list no longer shows up on the page although I didn't get any compile errors.
Can someone explain this to me and tell me when I should use one over the other?
This essentially is a feature of arrow functions in js.
const myArrowFunc = ({key1}) => ("Hello there! " + key1);
is essentially the same as
const myArrowFunc = ({key1}) => { return "Hello there! " + key1 };
when you leave out the curly brackets, the return is implicit.
When you include the curly brackets, you must explicitly use the return statement.
const someObj = { key1: "value1" };
const someReturn = myArrowFunc(someObj);
console.log(someReturn); // logs "Hello there! value1" to the console
()=>{} is the syntax of arrow function
When an arrow function only contains one line that return a value, e.g.:
() => {
return 1;
}
it can be simplified to
() => 1
Now what if you want to return an object directly? i.e. how to simplify
() => {
return { foo: "bar" }
}
Since an object also use {}, you cannot write {foo: "bar"} directly after the arrow as it will be treated as the function body. Wrapping the object within () solves the problem since a () chunk must be an expression. The above example can be simplified to
() => ( { foo : "bar" } )
This question already has an answer here:
How to destructure option argument with all default values in ES6?
(1 answer)
Closed 3 years ago.
I have a problem with referencing to data with this while trying to declare default parameters combined with destructuring. Anyone knows how to do it?
activated () {
this.fillData()
},
data () {
return {
chartData: {
distributionInitialData: {
// data here
}
}
}
},
methods: {
fillData ({
must = this.chartData.distributionInitialData,
nice = this.chartData.distributionInitialData
}) {
// do something
// function doesn't even get here because it gets error:
// TypeError: Cannot read property 'must' of undefined
// at VueComponent.fillData (Component.vue?4e6a:230)
// at VueComponent.activated (Component.vue?4e6a:123)
}
}
You need to set the default value for the parameter(Object), but not to its properties.
methods: {
fillData ({must, nice} = {
must: this.chartData.distributionInitialData,
nice: this.chartData.distributionInitialData
}) {
// do something
}
}
Updated by Bergi's advice.
methods: {
fillData ({
must: this.chartData.distributionInitialData,
nice: this.chartData.distributionInitialData
} = {}) {
// do something
}
}
FYI, here is a simple codepen.
You can do.
fillData ({ must, nice}) {
must = must || this.chartData.distributionInitialData
nice = nice || this.chartData.distributionInitialData
// do something
}
So the issue has to do with how Vue binds the methods to the component as it is created. The function definition does not have access to the instance, but inside of it you may use this.
The easiest solution would be to do an immediate check for undefined and set based on the desired default.
fillData({ must, nice }) {
if (must === undefined) must = this.chartData.distributionInitialData;
if (nice === undefined) nice = this.chartData.distributionInitialData;
// any other code here
}
You might also try playing around with arrow functions to see if it fixes this, since that was introduced to be bound to this in a more concrete way. Perhaps something like this:
fillData = ({
must = this.chartData.distributionInitialData,
nice = this.chartData.distributionInitialData
}) => {
// any other code here
}
I came across this piece of code here, and I noticed that const data is declared inside the brackets. I thought you had to use the key: value format inside the brackets when creating an object. How does this work?
data = {
const data = await d3.tsv("https://gist.githubusercontent.com/mbostock/8033015/raw/01e8225d4a65aca6c759fe4b8c77179f446c5815/unemployment.tsv", (d, i, columns) => {
return {
name: d.name.replace(/, ([\w-]+).*/, " $1"),
values: columns.slice(1).map(k => +d[k])
};
});
return {
y: "% Unemployment",
series: data,
dates: data.columns.slice(1).map(d3.utcParse("%Y-%m"))
};
}
That is not valid javascript. The reason it works is that Observable has its own syntax. It's deliberately designed to be similar to javascript, but it isn't actually javascript. You can read more about this here:
https://observablehq.com/#observablehq/observables-not-javascript
The code above is not a valid javascript code.
observableHQ is using its own parser to achieve that https://github.com/observablehq/parser the code is translated to the following:
const chart = (arguments) => {
// code...
}
I have a node js script that invokes a Yeoman generator that I wrote and I would like to skip the prompting step since I'm passing the data for the generator from the script. I searched the documentation but I didn't find anything relevant for this. Is it possible at all?
My script looks like this
const yeoman = require('yeoman-environment');
const env = yeoman.createEnv();
env.lookup(() => {
env.run('mygenerator:subgenerator --moduleName Test3', {'skip-install': true, 'skip-prompting': true }, err => {
console.log('done');
});
});
And my generator has nothing special:
const BaseGenerator = require('./../base/index.js');
module.exports = class extends BaseGenerator {
constructor(args, opts) {
super(args, opts);
this.props = opts;
const destinationFolder = args.destinationFolder || '';
const moduleName = args.moduleName || '';
this.props = {
moduleName,
destinationFolder,
};
}
prompting() {
//...
}
writing() {
//...
}
};
I know that the generator gets the data I'm passing from the script. I potentially I could have a generator which deals with input and another one only for writing the files. But it'd be nice to have only one code and be able to skip some steps.
I saw in some stackoverflow answers that people pass the { 'skip-install': true } option to the generator. Then I tried to pass { 'skip-prompting': true }, but it doesn't do anything.
Thank you!
EDIT
The way that I solved this is the following:
All my sub generators extend a BaseGenerator that I wrote, which is the one that extends from Yeoman. In my BaseGenerator I added this method:
shouldPrompt() {
return typeof this.props.options === 'undefined' ||
(typeof this.props.options.moduleName === 'undefined' &&
typeof this.props.options.destinationFolder === 'undefined');
}
I only use 2 parameters in my generators, moduleName and destinationFolder. So, that's all I want to check. Then, in the sub generators I added this:
prompting() {
if (this.shouldPrompt()) {
this.log(chalk.red('Reducer generator'));
const prompts = [ /*...*/ ];
return this.prompt(prompts).then((props) => { this.props.options = props; });
}
}
You'll want to define options or arguments to accept these arguments from the terminal: http://yeoman.io/authoring/user-interactions.html
Then, just use JavaScript to run or not the this.prompt() call (with if/else structure or any other conditional that works for your use case)
Remember that Yeoman is still only JS code :)