-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fill textarea with response from backend #109
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After fetching the response we need to fill the textarea with the response. THis is only half done.
app/actions/index.ts
Outdated
url: url | ||
}) | ||
.then(response => response) | ||
.then(response => dispatch(fetchSuccess(response) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can avoid this second then
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are storing only response, the use response.data
.
But I think we need to store the response type as well
app/actions/index.ts
Outdated
.then(response => response) | ||
.then(response => dispatch(fetchSuccess(response) | ||
.catch(err => err) | ||
.then(err => dispatch(fetchFailure(err))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dispatch failure directly from catch
app/components/request_list.tsx
Outdated
@@ -22,6 +22,7 @@ export interface RequestObj { | |||
disableInterceptor:React.ChangeEvent<HTMLButtonElement>; | |||
updateInterceptorStatus:React.ChangeEvent<HTMLButtonElement>; | |||
isInterceptorOn:object; | |||
fetchResponse:React.MouseEvent<HTMLButtonElement> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come this is React.MouseEvent
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since fetchResponse
is defined on onClick
event, it is supposed to be React.MouseEvent
i feel. Ref :https://reactjs.org/docs/events.html#mouse-events
app/reducers/rootReducer.ts
Outdated
return { | ||
...state, | ||
isInterceptorOn: {...state.isInterceptorOn, [action.payload.tabId]: action.payload.value} | ||
}; | ||
case actionType.FETCH_DATA_SUCCESS: { | ||
return {...state, response : action.response}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to store response for each and every urls. THis is will overwrite the response when we fetch for second url
app/actions/index.ts
Outdated
method: method, | ||
url: url | ||
}) | ||
.then(response => dispatch(response)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can't just dispatch
? where is the action?
app/actions/index.ts
Outdated
url: url | ||
}) | ||
.then(response => dispatch(response)) | ||
.catch(err => dispatch(err)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
action missing
app/reducers/rootReducer.ts
Outdated
...state.responseData, | ||
[action.payload.tabId]: { | ||
...state.responseData[action.payload.tabId], | ||
[action.payload.index]: action.payload.error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why we are setting error in response data?
app/reducers/rootReducer.ts
Outdated
return {...state, responseData : { | ||
...state.responseData, | ||
[action.payload.tabId]: { | ||
...state.responseData[action.payload.tabId], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is suppose to be requestId
app/actions/index.ts
Outdated
return function (dispatch) { | ||
axios({ | ||
method: method, | ||
url: url |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to pass the headers as well.
app/actions/index.ts
Outdated
} | ||
export function fetchResponse(url:string,method:string, tabId:number, index: number) { | ||
return function (dispatch) { | ||
axios({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return the promise
… after fetching responseText
… after fetching responseText
name="responseText" | ||
className="responseText" | ||
defaultValue={textAreaValue } | ||
key={textAreaValue} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added key attr to force re-render of textarea
if changing defaultValue after clicking the fetchResponse (X)
button
README.md
Outdated
the extension will not mock any previously intercepted calls. | ||
The toggle switch is used to disable `INTERCEPTOR`. If the toggle is switched to `OFF` state, it displays a message saying `Interception Disabled` as below. | ||
|
||
<img src="images/interceptor_disabled.png" alt="Message shown by Interceptor on disabling"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are already on master why this is showing as change here?
app/actions/index.ts
Outdated
export function fetchResponse(url:string,method:string, requestId:number) { | ||
return { | ||
type: FETCH_DATA, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is suppose to be a async action right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is why we are using aliases
- https://github.com/tshaddix/react-chrome-redux/wiki/Advanced-Usage#alias
className="fetch-responsetext" | ||
onClick={() => { | ||
props.fetchResponse(props.rowProps.checkbox); | ||
textAreaValue = JSON.stringify(props.responseData[props.rowProps.checkbox.requestId]) || responseTextValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be there. no need for || responseTextValue
. thats should be handled in store.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
responseTextValue
holds the value that is propagated from onChange event
of textarea
. If there is nothing typed in the textarea, Then it holds a value of empty string. Here textAreaValue
holds the value that is propagated from the store as props
when the X(fetch response)
button is clicked. We could handle this in a if else
conditional, but not in a store I guess. Any other approach you can think of. Please refer : https://github.com/code-mancers/interceptor/blob/18a38363d3f4f4700cc6c6e40fa25f875f528d2d/app/components/Intercept_Components/InterceptTextBox.tsx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okey I understand the || responseTextvalue
part. but still this statement should not be inside the onClick.
This statement should be in the render
method.
}; | ||
|
||
export default { | ||
FETCH_DATA: fetchDataAlias |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't do this.
please export default fetchDataAlias
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did that according to the pattern defined here : https://github.com/tshaddix/react-chrome-redux/wiki/Advanced-Usage#alias . Should I change it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is confusing can we use the normal thing since we are not integrating anything with background.
3e6ebe8
to
6c2b626
Compare
package.json
Outdated
@@ -44,6 +44,7 @@ | |||
"test:watch": "jest --watch" | |||
}, | |||
"dependencies": { | |||
"@types/axios": "^0.14.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why these got updated, may be deliberate choice, but if not, ensure these changes don't happen. These can be caused due to running npm upgrade
instead of npm install
(or yarn equivalent)
app/store/aliases.ts
Outdated
dispatch(fetchSuccess(data, requestId)); | ||
dispatch(handleRespTextChange(data.data, requestId)) | ||
}) | ||
.catch(err => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try to avoid catch
when not required. The second argument to then
here has the same affect as what catch does. using a .catch
handler would mean that any JS errors or other errors also get caught. Not a huge problem here, but that can become a habit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The catch
block here is executed in case the axios
lib isn't able to complete and fetch the response. Don't you recoemmend using this in case the server returns a error such as 404
or 500
. Refer this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case of axios rejecting for any reason (be it a problem with axios itself, or may be a network call failed), the second argument of .then
gets called. There are various reasons why they might've suggested using a catch
block but IME, it's a good practice to not abuse catch.
const fetchDataAlias = (payload: object) => { | ||
return dispatch => { | ||
const {method, url, requestId, requestHeaders} = payload.requestDetails; | ||
const requestHeadersObject = requestHeaders.reduce((accumulatedObj, reqHeaderNameValuePair) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain what's the intent of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In axios, if we need to pass the request headers while making a request, we need to specify it this way headers: {'X-Requested-With': 'XMLHttpRequest'},
. But from the background script, we get the headers in the following format.
requestHeaders : {
[0] : {name : 'X-Requested-With' , value : 'XMLHttpRequest'},
[1] : ...
}
So the function returns the headers in the way that axios requires.
Ref: https://github.com/axios/axios#request-config
@@ -2,12 +2,19 @@ import * as React from "react"; | |||
import {RequestHeaderList} from "./RequestHeaderList"; | |||
|
|||
export const InterceptTextBox = props => { | |||
const isObject = (val:any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A simpler check for this would be:
return !value && typeof val === 'object';
So that would return true only if the value is truthy, and it's a type of object. null
is also an object, but that's covered in the first check. stringify of a function is pretty much a noop, so that check is not required, we can treat it as not an object.
const responseTextValue = props.responseText[props.rowProps.checkbox.requestId] || defaultResponseText; | ||
const statusCodeValue = props.statusCodes[props.rowProps.checkbox.requestId] || defaultStatusCode; | ||
const contentTypeValue = props.contentType[props.rowProps.checkbox.requestId] || defaultContentType; | ||
const responseTextValue = isObject(props.responseText[requestId]) ? JSON.stringify(props.responseText[requestId]) : props.responseText[requestId] || defaultResponseText; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, it's more cleaner and easy to follow if the type of data is consistent: either always ensure it's an object, or ensure it's always a string (at this function call site). let the caller do the processing. That way, your main interception code doesn't need to handle all kinds of complex marshalling logic.
<label htmlFor="">Response Text</label> | ||
<label className="responseTextlabel">Response Text</label> | ||
<span | ||
title="Fetch Response Text" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use a <a>
or a button
tag for this? Also, title here doesn't seem to suggest what the action does
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, wanted that to replace that with an icon before the release. Just put up a placeholder span
tag for now
import { createLogger } from 'redux-logger' | ||
import { Middleware } from 'react-redux/node_modules/redux'; | ||
import thunkMiddleware from 'redux-thunk'; | ||
import aliases from './aliases' | ||
import { alias } from 'react-chrome-redux'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refer this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, more precisely, why do you want to use this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, I think I understand.
…ating with values from server
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are we showing the error message when fetch
fails?
const responseTextValue = props.responseText[props.rowProps.checkbox.requestId] || defaultResponseText; | ||
const statusCodeValue = props.statusCodes[props.rowProps.checkbox.requestId] || defaultStatusCode; | ||
const contentTypeValue = props.contentType[props.rowProps.checkbox.requestId] || defaultContentType; | ||
let responseTextValue = props.responseText[requestId] || defaultResponseText; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why let
. can be const
onClick={() => { | ||
props.fetchResponse(props.rowProps.checkbox) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix indentation.
app/store/aliases.ts
Outdated
dispatch(fetchSuccess(JSON.stringify(data.data), requestId)); | ||
}) | ||
.catch(err => { | ||
dispatch(fetchFailure("", requestId)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error message can't be blank.
app/store/aliases.ts
Outdated
.then(data => { | ||
dispatch(fetchSuccess("", requestId)) | ||
dispatch(handleRespTextChange(JSON.stringify(data.data), requestId)) | ||
dispatch(fetchSuccess(JSON.stringify(data.data), requestId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid repeated calls of JSON.stringify
#53