I am working on a react native application and on having a POST call with Observable.fromPromise, I am getting the below response, but I am not sure how to capture the response in terms of code and I amgetting some warnings as well
Response :
PromiseObservable {_isScalar: false, promise: Promise, scheduler: undefined}
promise: Promise
_40: 0
_55: Promise
_40: 0
_55: Promise
_40: 0
_51: 3
_55: Response
bodyUsed: true
headers: Headers {map: {…}}
ok: true
status: 200
statusText: undefined
type: "default"
url: "http://localhost:9999/testPath/pathData"
_bodyBlob: Blob {_data: {…}}
_bodyInit: Blob {_data: {…}}
__proto__: Object
_65: 2
_72: null
__proto__: Object
_65: 3
_72: null
__proto__: Object
_65: 3
_72: null
__proto__: Object
scheduler: undefined
_isScalar: false
__proto__: Observable
Warning :
YellowBox.js:67 Possible Unhandled Promise Rejection (id: 0):
Response {
"_bodyBlob": Blob {
"_data": Object {
"blobId": "D985543E-CD51-470C-91F9-3407AE59FDA1",
"name": "test-data",
"offset": 0,
"size": 0,
"type": "application/json",
},
},
"_bodyInit": Blob {
"_data": Object {
"blobId": "D985543E-CD51-470C-91F9-3407AE59FDA1",
"name": "test-data",
"offset": 0,
"size": 0,
"type": "application/json",
},
},
"bodyUsed": true,
"headers": Headers {
"map": Object {
"content-type": "application/json; charset=UTF-8",
"server": "Jetty(9.2.z-SNAPSHOT)",
"transfer-encoding": "Identity",
},
},
"ok": true,
"status": 200,
"statusText": undefined,
"type": "default",
"url": "http://localhost:9999/testPath/pathData",
}
I am using mergeMap to capture the response, not sure why is it not working in this case
Code:
const testEpic: Epic<Action, ReduxState> = (
action$: ActionsObservable<any>,
store: MiddlewareAPI<any, ReduxState>,
) =>
action$
.ofType(TEST_GET)
.mergeMap((action) => {
return Observable.merge(
.fetch('/testPath/pathData', payload) // return part which is working properly
.mergeMap((response) => {
// calls not coming here for POST, PUT, DELETE even though it is status 200
})
)
}
)
.catch((error) => {
})
Try this
fetch("/testPath/pathData", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
I have resolved it,actually it was going inside 'error' because of mismatch of contentType
Related
I am writing a react native expo app that utilizes a .NET backend that I've already established and has worked quite well for a while. Recently, I've gotten to the point of attempting local http requests with axios for my mobile app rather than mock data, and it worked wonderfully for a bit. I have a few get requests that are called in a useEffect like this:
useEffect(() => {
async function getAll() {
const response = await axios({
method: 'GET',
url: `${baseUrl}/ItemName`,
headers: {
authorization: `Bearer ${authToken}`,
'content-type': 'application/x-www-form-urlencoded'
}
}).catch(err => console.log(err));
if(response?.data) {
setItemName(response.data);
}
}
getAll();
}, []);
Then after that was working, I wanted to put in authentication within the app itself rather than using the backend Swagger and copying the token every 30 minutes. Made a signup page and the form worked just fine, but when I made the new axios post request, none of the requests worked - even those that were working before hand. The post looks like this:
const postNewUser = async (values) => {
try {
const postObject = {
method: 'POST',
url: `${baseUrl}/User/Register`,
data: {
firstName: values.firstName,
lastName: values.lastName,
username: values.username,
password: values.password,
email: values.email,
phoneNumber: values.phone,
birthDate: moment(values.birthDate).toISOString()
},
headers: {
'content-type': 'application/json'
}
};
const response = await axios(postObject);
if(response) {
navigation.navigate('Login', {
desiredUsername: values.username
});
}
} catch(err) {
console.log('Error: ', err);
}
}
I've been googling for over a week now trying different answers multiple different times. I've tried updating my nodejs, tried different versions of axios, tried different baseUrls for the request (localhost, 10.0.2.2, and my personal IP) but none of them work. Strangely, localhost and my IP both return very quickly, and 10.0.2.2 takes a solid 30 seconds but returns the same error message.
I have put a log into the user controller on my backend to show whether or not I'm actually hitting the backend or not, and with postman or swagger I get there just fine. With the mobile axios call I don't hit that log, so I'm not even getting to the backend at all. Instead I'm getting a not-so-useful error as follows:
Stack: AxiosError#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:114554:29
handleTimeout#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:115572:39
dispatchEvent#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:30065:31
setReadyState#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:28693:33
__didCompleteResponse#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:28499:29
emit#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:2310:40
__callFunction#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:21321:36
#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:21071:31
__guard#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:21269:15
callFunctionReturnFlushedQueue#http://personalIP:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=ios&dev=true&hot=false:21070:21
callFunctionReturnFlushedQueue#[native code]
Message: timeout exceeded
Name: AxiosError
Code: ECONNABORTED
Config: {
"adapter": [
"xhr",
"http"
],
"data": "{\"firstName\":\"Test\",\"lastName\":\"Test\",\"username\":\"test\",\"password\":\"P#ssw0rd\",\"email\":\"email#example.com\",\"phoneNumber\":\"5555555555\",\"birthDate\":\"2022-11-27T19:13:57.458Z\"}",
"env": {
"Blob": [Function Blob
],
"FormData": [Function FormData
]
},
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
"maxBodyLength": -1,
"maxContentLength": -1,
"method": "post",
"timeout": 0,
"transformRequest": [
[Function transformRequest
]
],
"transformResponse": [
[Function transformResponse
]
],
"transitional": {
"clarifyTimeoutError": false,
"forcedJSONParsing": true,
"silentJSONParsing": true
},
"url": "http://10.0.2.2:5000/api/User/Register",
"validateStatus": [Function validateStatus
],
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN"
}
Request: {
"DONE": 4,
"HEADERS_RECEIVED": 2,
"LOADING": 3,
"OPENED": 1,
"UNSENT": 0,
"_aborted": false,
"_cachedResponse": undefined,
"_hasError": true,
"_headers": {
"accept": "application/json, text/plain, */*",
"content-type": "application/json"
},
"_incrementalEvents": false,
"_lowerCaseResponseHeaders": {},
"_method": "POST",
"_perfKey": "network_XMLHttpRequest_http://10.0.2.2:5000/api/User/Register",
"_performanceLogger": {
"_closed": false,
"_extras": {},
"_pointExtras": {},
"_points": {
"initializeCore_end": 606677771.370125,
"initializeCore_start": 606677745.343875
},
"_timespans": {
"network_XMLHttpRequest_http://10.0.2.2:5000/api/User/Register": [Object
],
"network_XMLHttpRequest_http://personalIp:19000/logs": [Object
],
"network_XMLHttpRequest_http://personalIp:19000/symbolicate": [Object
],
"network_XMLHttpRequest_http://personalIp:5000/api/User/Register": [Object
],
"network_XMLHttpRequest_http://localhost:5000/api/User/Register": [Object
]
}
},
"_requestId": null,
"_response": "The request timed out.",
"_responseType": "",
"_sent": true,
"_subscriptions": [],
"_timedOut": true,
"_trackingName": "unknown",
"_url": "http://10.0.2.2:5000/api/User/Register",
"readyState": 4,
"responseHeaders": undefined,
"status": 0,
"timeout": 0,
"upload": {},
"withCredentials": true
}
I'm testing this currently on my mobile expo app. I've tested in the past on the web version but SecureStore doesn't work with web. I was able to confirm before adding the new requests that the mobile version was able to call the getAll just fine before the signup was added.
I have an api with the following schema.
[
{
"id":1,
"question": {
"description" : "",
"user": "",
},
"answers:[
{
"detailedAnswer" : "",
"user" : "",
},
{
"detailedAnswer" : "",
"user" : "",
}
]
},
{
"id":2,
"question": {
"description" : "",
"user": "",
},
"answers:[
{
"detailedAnswer" : "",
"user" : "",
}
]
}
]
So In my react app I need to add new object (given below) to the answers array of that particular id everytime I click submit button.
{
"detailedAnswer" : "",
"user" : "",
},
So my question is how can I push new object to the answers array ?
So, I tried Post method it shows "Bad request 400 error" and when I use "PUT" method, the object instead of appending item to the array replaces the exisitng object.
const postAnswer = async (e) => {
e.preventDefault();
const addAnswer = {
detailedanswer: answer,
user: user,
};
await fetch(`${API}/home/${id}`, {
method: "POST",
body: JSON.stringify(addAnswer),
headers: {
"Content-Type": "application/json",
},
})
.then((response) => {
response.json()
console.log(response)
})
.then((data) => {
console.log(data)
})
.then(() => alert("Answer added successfully"))
.then(() => navigate(`/home/${id}`))
.catch((err) => console.log(err.message))
}
This is the error I got
POST https://635b6c48aa7c3f113dbc75cb.mockapi.io/home/5 400 ( Bad Request )
Response {type: 'cors', url: 'https://635b6c48aa7c3f113dbc75cb.mockapi.io/home/5', redirected: false, status: 400, ok: false, …}
There is no error in the URL mentioned still I am getting bad request error.
My url if opened on browser gives the following error:(attached image)
Body of my api call looks like below :
{
"entityId": 4071,
"listViewId": 0,
"asLookup": false,
"retrieveAllFields": true,
"fullTextSearch": "",
"query": [
],
"pagination": {
"pageNumber": 0,
"recordsCountPerPage": 0
},
"sorting": {
"fieldId": 0,
"direction": 0
}
}
I am calling api in react native using fetch below :
try {
let response = await fetch('url', {
method: 'POST',
headers: {
'tenantid': '1',
'Content-Type': 'application/json',
'language': '0',
},
body: JSON.stringify({
entityId: 4071,
listViewId: 0,
asLookup: false,
retrieveAllFields: true,
fullTextSearch: "",
query: [
],
pagination: {
pageNumber: 0,
recordsCountPerPage: 0
},
sorting: {
fieldId: 0,
direction: 0
}
})
})
let json = await response.json();
console.log("This is response" + json)
this.setState({records: json.results, isFetching:false});
}catch(error){
this.setState({errorMessage:error})
console.log("This is error"+error)
}
This gives me response : Network failed request. Also tried with the inverted commas, still same response. I am newbie in react native but I have made api calls in the past but this one wouldnt work. If anyone can look into this, would be of great help!
did you use the correct url ?
it should looks like something like this
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue'})
}).then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
});
maybe you should look on the documentations
https://reactnative.dev/docs/network
I'm fairly to new to React and I can't seem to be able to successfully make a call to an external API using Axios.
The guidelines of the external API are:
Request (in case we know all the parameters)
{
"service": "login",
"username": "john",
"password":"aitis",
"appId": "2001",
"COMPANY": "1000",
"BRANCH": "1000",
"MODULE": "0",
"REFID": "1",
---- optional ---
"LOGINDATE": "2017-12-31 13:59:59",
"TIMEZONEOFFSET": -120
}
Response
{
"success": true,
"clientID": "Wj8Te8EqWghDM......... .....wYGtzlyc1At%2bPrG8t"
}
My code is:
componentDidMount() {
axios.get('http://...serverurl....', {
params: {
service: 'login',
username: 'john',
password: 'aitis',
appID: '2001',
company: '1000',
branch: '1000',
module: '0',
refid: '1'
},
headers: {
'accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS'
}
})
.then(response => console.log(response));
}
Instead of getting the clientID response I get this:
Response
{data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
data:
success: false
errorcode: 0
error: "JSON Object must begin with "{" at character 2 of service=login&username=john&password=aitis&appID=2001&Company=1000&Branch=1000&Module=0&Refid=1 JSON Syntax Error : at charact↵
error on character : 2"
__proto__: Object
status: 200
statusText: ""
...
Is something wrong with my call?
Thanks in advance.
If want to send a GET request with those params set those in URL
const URL = `${baseURL}/url?service=login&username=jhon&password=aitis&appID=2001&company=1000&branch=1000&module=0&refid=1`;
axios.get(URL).then(response => console.log(response));
I figured it out. I had to use axios.post instead of axios.get.
Thank you all very much
I use rxjs v6 and redux-observable v1
I have epic that send request to server and try to test epic like in doc. When I run test epic before send request emit 3 actions and it see on test result, but when epic comes to ajax call test finish. To mock request I use nock lib.
Epic:
import { ofType } from 'redux-observable'
import { of, merge, from } from 'rxjs'
import {
switchMap,
catchError
} from 'rxjs/operators'
import { apiRequest, handleAsyncError$ } from '../../async/lib'
import { actions as asyncActions } from '../../async'
import { LOADING_TYPES } from '../../async/constants'
import { actions as authActions } from '../reducer'
const setSignInLoading = (status) => of(asyncActions.setLoading({ type: LOADING_TYPES.signIn, status }))
const emitSignInPending = () => merge(
setSignInLoading(true),
of(authActions.signInPending())
)
const emitSignInSuccess = (payload) => merge(
setSignInLoading(false),
of(authActions.signInSuccess(payload))
)
const emitSignInFailed = (payload) => merge(
setSignInLoading(false),
handleAsyncError$({
action: authActions.signInFailure,
payload
})
)
// --------- ajax call -----------
const startSignIn = (payload) => apiRequest({
path: '/auth/signin/manager',
method: 'post',
body: payload
})
const mapSignInAction$ = ({ payload }) => merge(
// --------- emit 3 actions -----------
emitSignInPending(),
// --------- finish test -----------
startSignIn(payload)
.pipe(
switchMap((emitSignInSuccess)),
catchError(emitSignInFailed)
)
)
const signInEpic = action$ =>
action$
.pipe(
ofType(authActions.signIn),
switchMap(mapSignInAction$)
)
export default signInEpic
apiRequest:
import { get } from 'lodash'
import { throwError } from 'rxjs'
import { ajax } from 'rxjs/ajax'
import { map, catchError } from 'rxjs/operators'
import { API } from '../../../../config'
const apiRequest = ({ token, path, method, body }) => {
const settings = {
url: `${API}${path}`,
headers: { 'Content-Type': 'application/json' },
responseType: 'json',
crossDomain: true,
method,
body
}
if (token) {
settings.headers['Authorization'] = `Bearer: ${token}`
}
return ajax(settings)
.pipe(
catchError((request) => {
const error = get(request, 'response.error')
return throwError({ error, request })
}),
map(({ response }) => response)
)
}
export default apiRequest
Test:
nock(API)
.post('/auth/signin/manager')
.reply(200, response)
scheduler.run(({ hot, expectObservable }) => {
const source = hot('-a|', { a: authActions.signIn({ email: 'manager', password: '123123' }) })
const output$ = epic(source)
expectObservable(output$).toBe('-(bcde)', {
b: asyncAction.setLoading({ type: 'signIn', status: true }),
c: authActions.signInPending(),
d: asyncAction.setLoading({ type: 'signIn', status: false }),
e: authActions.signInSuccess(response)
})
})
Result:
Expected:
[{"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": {"status": true, "type": "signIn"}, "type": "[8] async/setLoading"}}}, {"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": undefined, "type": "[3] [2] auth/signIn/pending"}}}, {"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": {"status": false, "type": "signIn"}, "type": "[8] async/setLoading"}}}, {"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": {"data": {"token": "skldjf", "user": {"email": "manager", "id": 2, "passwordHash": "asdf", "passwordSalt": "6819c23dc7", "role": {"name": "user"}, "roleId": 1}}}, "type": "[4] [2] auth/signIn/success"}}}]
Received:
[{"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": {"status": true, "type": "signIn"}, "type": "[8] async/setLoading"}}}, {"frame": 1, "notification": {"error": undefined, "hasValue": true, "kind": "N", "value": {"error": false, "payload": undefined, "type": "[3] [2] auth/signIn/pending"}}}]
Ajax resolves as microtask so epic doesn't emit it sync, so marble diagrams can't handle it, I can't find how to do it with marble diagrams. So simple solutions is:
it('return token and user 2', async (done) => {
const response = {...}
nock(API)
.post('/auth/signin/manager')
.reply(200, response)
const source = authActions.signIn({ email: 'manager', password: '123123' })
const action$ = ActionsObservable.of(source)
epic(action$).pipe(toArray()).subscribe((actions) => {
expect(actions).toEqual([
asyncAction.setLoading({ type: 'signIn', status: true }),
authActions.signInPending(),
asyncAction.setLoading({ type: 'signIn', status: false }),
authActions.signInSuccess(response)
])
done()
})
})
Please write if you found how do it with marble diagrams.