Assign request response to the global variable - Module Javascript - javascript

Suppose I create a BookController and have a function like the example below in this controller:
import Fetch from './Fetch.js';
// GET
async function getAllBooks() {
const books = await Fetch.get('/books');
}
Still in the BookController.js file, could I export this function to call it in another js file as below?
function getAll() {
return getAllBooks();
}
export default {
getAll,
};
Another thing, is it possible to transform the const books into a global variable and export that variable so that I can use it anywhere?
Fetch.js
// Fetch.js
const _apiHost = 'https://api.example';
async function request(url, params, method = 'GET') {
const options = {
method,
headers: {
'Content-Type': 'application/json'
}
};
if (params) {
if (method === 'GET') {
url += '?' + objectToQueryString(params);
} else {
options.body = JSON.stringify(params);
}
}
const response = await fetch(_apiHost + url, options);
if (response.status !== 200) {
return generateErrorResponse('The server responded with an unexpected status.');
}
const result = await response.json();
return result;
}
function objectToQueryString(obj) {
return Object.keys(obj).map(key => key + '=' + obj[key]).join('&');
}
function generateErrorResponse(message) {
return {
status : 'error',
message
};
}
function get(url, params) {
return request(url, params);
}
function create(url, params) {
return request(url, params, 'POST');
}
function update(url, params) {
return request(url, params, 'PUT');
}
function remove(url, params) {
return request(url, params, 'DELETE');
}
export default {
get,
create,
update,
remove
};

In javascript we can use global variable with the use of window object.
declare book variable like window.books="some value" intead of const books.
in the same way use function also:
window.getAll = () => {
return getAllBooks();
}
and get value anywhere.

Related

axios error react interceptors request is not a function

i have a configuration with axios i am testing a feature to receive a list of students from an api, the problem is that it sends me an error:
TypeError:
constants_api_constants__WEBPACK_IMPORTED_MODULE_1_.default.interceptors.request
is not a function
For my axios configuration I use:
const options.GET_ALL_STUDENTS = {
method: "GET",
url: "/Student",
}
const BASE_API_URL = "https://localhost:7072/api";
const api = axios.create({
baseURL: `${BASE_API_URL}`,
});
const getStudents = () => {
return api.interceptors.request(options.GET_ALL_STUDENTS).use(
function request(success) {
return success;
},
function error(err) {
return err;
},
);
};
How I resolve my promise, (without interceptor this work fine):
function* fetchStudents() {
try {
const result1 = yield call(getStudents);
const studentList = createStudentListAdapter(result1.data);
yield put(fetchStudentsSuccess(studentList));
} catch (error) {
yield put(fetchStudentsFailure());
}
}
Interceptors are used to intercept any request/response before it goes to try/catch.
const getStudents = async () => {
try {
const res = await api(options.GET_ALL_STUDENTS);
// logic
} catch (e) {
// handle error
}
};
Interceptor
api.interceptors.request.use(
(request) => {
console.debug("Request", request.url);
return request;
},
(error) => {
console.debug("Request Failed", error.request.data.message);
return Promise.reject(error);
},
);

How to export a variable in javascript within a function?

I have the following function:
export function request(
searchKey,
apiEndpoint,
path,
params,
{ additionalHeaders } = {}
) {
const method = "POST";
return _request(method, searchKey, apiEndpoint, path, params, {
additionalHeaders
}).then(response => {
return response
.json()
.then(json => {
var my_json = update(params)
const result = { response: response, json: json };
return result;
})
});
}
I want to export the variable my_json to another .js file. I already tried with export { my_json }, but it only works if I do that on the top of the document, which doesn't work in my case. Does anyone have an idea?
You can't export a variable which is inside a function but you can definitely get the value stored in my_json by the help of a callback function written in another javascript file.
Try using:
export function request(
searchKey,
apiEndpoint,
path,
params,
{ additionalHeaders } = {},
callback
) {
const method = "POST";
return _request(method, searchKey, apiEndpoint, path, params, {
additionalHeaders
}).then(response => {
return response
.json()
.then(json => {
var my_json = update(params);
callback(my_json);
const result = { response: response, json: json };
return result;
})
});
}
and in the other file define a function callback like:
function callback(data){
// assign this data to another variable so that one can use it
console.log(data)
}
and while calling the request function add one more argument as callback.
Hope this helps.

Service call is not going in react-native. Getting warning like "Possible unhandled Promise Rejection, Reference error: response is not defined"

I am new to react native and making service call for the first time. My problem is service call is not going and getting warning like
Possible unhandled Promise Rejection, Reference error: response is not defined.
I am trying to hit loginUser function.
Api.js
const BASE_URL = "http://localhost:8200";
export const api = async (url, method, body = null, headers = {}) => {
try {
const endPoint = BASE_URL.concat(url);
const reqBody = body ? JSON.stringify(body) : null;
const fetchParams = {method, headers};
if((method === "POST" || method === "PUT") && !reqBody) {
throw new Error("Request body required");
}
if(reqBody) {
console.log("ReQBody--->"+reqBody);
fetchParams.headers["Content-type"] = "application/json";
fetchParams.body = reqBody;
}
const fetchPromise = await fetch(endPoint, fetchParams);
const timeOutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject("Request Timeout");
}, 3000);
});
const response = await Promise.race([fetchPromise, timeOutPromise]);
return response;
} catch (e) {
return e;
}
}
export const fetchApi = async (url, method, body, statusCode, token = null, loader = false) => {
console.log("In FetchAPi Function");
try {
const headers = {}
const result = {
token: null,
success: false,
responseBody: null
};
if(token) {
headers["securityKey"] = token;
}
const response = await api(url, method, body, headers);
console.log("fetchApi-->>"+response);
if(response.status === statusCode) {
result.success = true;
let responseBody;
const responseText = await response.text();
try {
responseBody = JSON.parse(responseText);
} catch (e) {
responseBody = responseText;
}
result.responseBody = responseBody;
return result;
}
let errorBody;
const errorText = await response.text();
try {
errorBody = JSON.parse(errorText);
} catch (e) {
errorBody = errorText;
}
result.responseBody = errorBody;
console.log("FetchApi(Result)--->>"+result);
throw result;
} catch (error) {
return error;
}
}
auth.actions.js
export const loginUser = (payload) => {
console.log("In LoginUser function2");
return async (dispatch) => {
<-----**I am not able to enter into this block**------>
try {
dispatch({
type: "LOGIN_USER_LOADING"
});
console.log("In LoginUser function3");
const response = await fetchApi("/login", "POST", payload, 200);
if(response.success) {
dispatch({
type: "LOGIN_USER_SUCCESS",
});
dispatch({
type: "AUTH_USER_SUCCESS",
token: response.token
});
dispatch({
type: "GET_USER_SUCCESS",
payload: response.responseBody
});
return response;
} else {
throw response;
}
} catch (error) {
dispatch({
type: "LOGIN_USER_FAIL",
payload: error.responseBody
});
return error;
}
}
}
In console log, I can't see anything in network tab. In the android emulator, the mentioned warning has come.
My console tab
I see that your BASE_URL is served using an http endpoint. You can only make requests to https endpoints from react native projects. A possible workaround is to use ngrok. Just download it and run ./ngrok http 8200 since your port number is 8200. It will expose an HTTPS endpoint and replace your BASE_URL with that link and try fetching the data again.
I use the following code to make API calls. See if you can integrate it in your code. it is quite simple:
In a class called FetchService:
class FetchService {
adminAuth(cb, data) {
console.log('here in the fetch service');
return fetch(
baseURL + "login",
{
method: "POST",
headers: {
Accept: "application/json",
},
body: data
}
)
.then((response) => response.json())
.then(responsej => {
cb(null, responsej);
})
.catch(error => {
cb(error, null);
});
}
}
export default FetchService;
Then call it from your component using:
import FetchService from './FetchService';
const fetcher = new FetchService;
export default class LoginScreen extends React.Component {
fetchData() {
const data = new FormData();
data.append('username',this.state.username);
data.append('password',this.state.password);
fetcher.wastereport((err, responsej) => {
if(err) {
//handle error here
} else {
//handle response here
}
}, data);
}
}

apisauce (axios wrapper) - Can i handle the response error to write once and automatically called instead of manually add if else

I have too many API to called in my project and I'm using apisauce to communicating into API
I've an example code :
api.get("myUrl")
.then((response)=>{
console.log(response)
if(response.ok && response.status == 200){
//displaying data to screen
} else{
//display alert failed to call API
}
})
for now I want to handle if the authorization token is failed I want to redirect to login page, but I don't want to add the code authorization token is failed to all of my api request
Is there a way to create code else if(!response.ok && response.status == 401){redirectToLogin()} once instead of add this code into all of my API.get?
For our react-native app I create a class with own get, delete, put, update methods, which handles errors and then invoke apisauce.get e.t.c.
I use flow type annotations, but it'll be nicer using typescript for easily creating private methods.
type ApiRequest = (url: string, payload?: Object) => Promise<ApiResponse>;
export class Api {
apiSauce: {
get: ApiRequest,
post: ApiRequest,
put: ApiRequest,
delete: ApiRequest,
};
constructor(baseURL: string) {
this.apiSauce = apisauce.create({
baseURL,
headers: {
"Cache-Control": "no-cache",
},
timeout: 60 * 1000,
});
}
_get = async (url: string, payload?: Object) => {
const res = await this._handleResponse(this.apiSauce.get, { url, payload });
return res;
};
_put = async (url: string, payload?: Object) => {
const res = await this._handleResponse(this.apiSauce.put, { url, payload });
return res;
};
_post = async (url: string, payload?: Object) => {
const res = await this._handleResponse(this.apiSauce.post, { url, payload });
return res;
};
_delete = async (url: string, payload?: Object) => {
const res = await this._handleResponse(this.apiSauce.delete, { url, payload });
return res;
};
_handleResponse = async (apiRequest: ApiRequest, params: ApiRequestParams): Promise<ApiResponse> => {
const res = await apiRequest(params.url, params.payload);
return this._handleError(res);
};
_handleError = (res: ApiResponse) => {
if (!res.ok) {
if (res.status === 401 || res.status === 403) {
// **redirect to login page**
}
if (res.data && res.data.message) {
showNotification(res.data.message);
}
showNotification(res.problem);
}
return res;
};
getUser = async (userId: string): Promise<User> => {
const response = await this._get(`users/{userId}`);
return transformUserApiResponse(response.data);
};
}
const MyApi = new Api(BASE_URL);

Sinon stub returns empty response when mocking multiple methods of same object

I am trying to mock two methods in a object using sinon. One of it returns the expected response but the other method returns an empty json.
describe("Unit test cases ", () => {
describe("scenario 1", function() {
let getResponse, updateResponse;
before(function() {
getResponse = sinon
.stub(DataApi.prototype, "getState")
.returns(
Promise.resolve(
JSON.parse(
fs.readFileSync("./test/get-response.json").toString("utf8")
)
)
);
updateResponse = sinon
.stub(DataApi.prototype, "updateState")
.returns(
Promise.resolve(
JSON.parse(
fs.readFileSync("./test/update-response.json").toString("utf8")
)
)
);
});
after(function() {
getResponse.restore();
updateResponse.restore();
});
it("TC1", () => {
let event;
var fn = function() {
try {
console.log(
"before testing" +
JSON.stringify(DataApi.prototype.updatePromoteState())
); // returns {} instead of response json
handle(event, context, callback);
} catch (error) {
throw error;
}
};
expect(fn).to.not.throw("Successfully Processed");
});
});
});
Source code for updatestate method
public updateState (authorization: string, xB3TraceId: string, xAppName?: string) : Promise<any> {
const localVarPath = this.basePath + '{abc}';
let localVarQueryParameters: any = {};
let localVarHeaderParams: any = (<any>Object).assign({}, this.defaultHeaders);
let localVarFormParams: any = {};
let localVarUseFormData = false;
let localVarRequestOptions: localVarRequest.Options = {
method: 'PUT',
qs: localVarQueryParameters,
headers: localVarHeaderParams,
uri: localVarPath,
json: true,
body: ObjectSerializer.serialize(promoteState, "PromoteState")
};
return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => {
localVarRequest(localVarRequestOptions, (error, response, body) => {
if (error) {
reject(error);
} else {
if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
resolve({ response: response, body: body });
} else {
reject({ response: response, body: body });
}
}
});
});
}
}
The source code for getState is also similar to the above.
How to mock multiple methods in the same method so that it returns the expected response.
How you use the stubs are correct and should work. And they are actually working, the problem is the mock methods here are returning promises (Promise.resolve(JSON.parse(...))).
console.log(
"before testing" +
JSON.stringify(DataApi.prototype.updatePromoteState())
); // returns {} instead of response json
The code above tries to log the promise, not the actual value.
You can add an await keyword before the function call and change the fn function to async. So it becomes more or less:
const fn = async () => {
try {
console.log(
'before testing' + JSON.stringify(DataApi.prototype.updateState()),
);
} catch (error) {
throw error;
}
};
or remove Promise.resolves within stub functions.

Categories

Resources