Skip to content
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

Merged
merged 30 commits into from
May 14, 2018

Conversation

amitmbee
Copy link
Contributor

#53

Copy link
Contributor

@revathskumar revathskumar left a 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.

url: url
})
.then(response => response)
.then(response => dispatch(fetchSuccess(response)
Copy link
Contributor

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.

Copy link
Contributor

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

.then(response => response)
.then(response => dispatch(fetchSuccess(response)
.catch(err => err)
.then(err => dispatch(fetchFailure(err)))
Copy link
Contributor

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

@@ -22,6 +22,7 @@ export interface RequestObj {
disableInterceptor:React.ChangeEvent<HTMLButtonElement>;
updateInterceptorStatus:React.ChangeEvent<HTMLButtonElement>;
isInterceptorOn:object;
fetchResponse:React.MouseEvent<HTMLButtonElement>
Copy link
Contributor

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 ?

Copy link
Contributor Author

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

return {
...state,
isInterceptorOn: {...state.isInterceptorOn, [action.payload.tabId]: action.payload.value}
};
case actionType.FETCH_DATA_SUCCESS: {
return {...state, response : action.response};
Copy link
Contributor

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

method: method,
url: url
})
.then(response => dispatch(response))
Copy link
Contributor

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?

url: url
})
.then(response => dispatch(response))
.catch(err => dispatch(err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

action missing

...state.responseData,
[action.payload.tabId]: {
...state.responseData[action.payload.tabId],
[action.payload.index]: action.payload.error
Copy link
Contributor

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?

return {...state, responseData : {
...state.responseData,
[action.payload.tabId]: {
...state.responseData[action.payload.tabId],
Copy link
Contributor

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

return function (dispatch) {
axios({
method: method,
url: url
Copy link
Contributor

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.

}
export function fetchResponse(url:string,method:string, tabId:number, index: number) {
return function (dispatch) {
axios({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return the promise

name="responseText"
className="responseText"
defaultValue={textAreaValue }
key={textAreaValue}
Copy link
Contributor Author

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">
Copy link
Contributor

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?

export function fetchResponse(url:string,method:string, requestId:number) {
return {
type: FETCH_DATA,
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

className="fetch-responsetext"
onClick={() => {
props.fetchResponse(props.rowProps.checkbox);
textAreaValue = JSON.stringify(props.responseData[props.rowProps.checkbox.requestId]) || responseTextValue;
Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Contributor Author

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 ?

Copy link
Contributor

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.

@amitmbee amitmbee force-pushed the Fill-textarea-with-response branch from 3e6ebe8 to 6c2b626 Compare May 2, 2018 11:20
package.json Outdated
@@ -44,6 +44,7 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@types/axios": "^0.14.0",
Copy link
Contributor

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)

dispatch(fetchSuccess(data, requestId));
dispatch(handleRespTextChange(data.data, requestId))
})
.catch(err => {
Copy link
Contributor

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

Copy link
Contributor Author

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

Copy link
Contributor

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) => {
Copy link
Contributor

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?

Copy link
Contributor Author

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) => {
Copy link
Contributor

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.

screenshot 2018-05-04 14 08 39

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;
Copy link
Contributor

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"
Copy link
Contributor

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

Copy link
Contributor Author

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';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer this

Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Contributor

@revathskumar revathskumar left a 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;
Copy link
Contributor

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)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix indentation.

dispatch(fetchSuccess(JSON.stringify(data.data), requestId));
})
.catch(err => {
dispatch(fetchFailure("", requestId))
Copy link
Contributor

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.

.then(data => {
dispatch(fetchSuccess("", requestId))
dispatch(handleRespTextChange(JSON.stringify(data.data), requestId))
dispatch(fetchSuccess(JSON.stringify(data.data), requestId));
Copy link
Contributor

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

@revathskumar revathskumar merged commit 7a76114 into master May 14, 2018
@revathskumar revathskumar deleted the Fill-textarea-with-response branch May 14, 2018 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants