Understanding what does Axios create do - javascript

I was asked to make API call to send data.
On Click in vue, I was firing this event
async facebookDataToSend () {
let campaignID = await this.$store.getters['CurrentInstance/id']
this.$axios.post(process.env.API_BASE_URL + 'faceeBookCampaign', { campaignID: campaignID }, { withCredentials: true })
},
But then, I was told to use API functions which already exsist in some xyz.js file.
My xyz.js file looks like this..
const rest = {
something: axios.create({
baseURL: process.env.API_BASE_URL,
withCredentials: true
}),
setClient: function (client) {
this.something = axios.create({
baseURL: process.env.API_BASE_URL,
withCredentials: true,
params: {
__somethingClient: client
}
})
this.client = client
}
}
Here, I am unable to comprehend how can I use this instance to make an api call So I viewed the code where they have already made the api call and saw something like this
const API = {
url: '/whateverHtml/',
method: 'post',
withCredentials: true,
data: {
'schemaType': 'something-event', // TODO FIXME
'field': 'description', // TODO FIXME
'html': this.model[this.field.key]
}
api.something.request(API).then(result => {
And I wasn't able to comprehend the code. For starters
What is request? I don't see my any method or property inside something in my rest variable
second why are they using withCredentials: true in their API object when they have already set up the property as true in rest object]
What are the pro's of using axios.create({ i.e what they are doing than what I initially did this.$axios.post(

request is a method defined by axios. Link to docs.
request allows you to make an HTTP call with any verb you want (POST, GET, DELETE, PUT). Most likely axios calls request from inside all the other helper methods (get, post), but this is an implementation details. One of the advantages of using request is that you don't have to hardcode the HTTP verb (POST, GET ...) and you can set it at run time depending on your input.
I see 2 reasons why they would set withCredentials:
setClient may or may not be called before something
for clarity: it's enough to look at the definition of something to realise that the client is using credentials and you don't need any extra information about how rest works.
I don't think the request for you to use something boils down to advantages of axios.$post vs axios.create. It's probably related more to how to organise your code.
Some advantages of using a separate module vs calling axios directly
when calling axios directly you are prepending base url all the time, when using a module for your REST API the base URL is tucked away and arguably makes your code easier to read
you can bake other options inside config and make sure they are used. For instance you may have an access token, the module can store that token and always added to any request. When calling axios by hand you need to remember this
you are decoupled from axios (to some degree)(1). When using a module you don't actually care if it's axios doing the requests or not.
You can add more API calls to the module that you can reuse in the future. I'm expecting xyz file to grow in time and your call to faceeBookCampaign to end up being a method on the rest variable. It makes more sense to end up using this.client and not something but this is up to the devs.
it keeps all the REST API calls in one place allowing you to build an SDK for that API, which as the project grows can have its own life cycle.
(1) I say that id decouples you to some degree because there are semantics that need to be kept so everything works. The returned object needs to have a request method that accepts a config object. The config need to conform to the same structure as the one that axios wants. But, you can always write an adapter for that, so you are actually decoupled from axios.

request here takes a config and returns a promise. I am guessing this approach is usually taken when you want to reuse a request object that is created using create (at least my sense).
I feel the request method is used to overwrite the initial configuration with new one defined in API. And, the double withCredentials should be an oversight.
OR, because API is defining a new config object, therefore when defined without withCredentials, it would overwrite the create's configuration.
Hence, it looks like its specified twice.

Related

Access the request object from Express inside a Mongoose Plugin

I have an API in ExpressJS and a middleware that gets executed before each endpoint controller:
app.use(segregationMiddleware);
app.get('/some-endpoint', controller1);
app.get('/some-endpoint-2', controller2);
The segregationMiddleware is used to look for some parameters in the request and then it calculates a value that then is stored in the request object as req.locals.domain so the controllers can access it.
In each Mongoose model, I define a field named domain using a Mongoose plugin (so I don't have to do it every time). That field is used to segregate my assets. This means that when the segregationMiddleware populates req.locals.domain = 'foo' for example, if I make a model.find({}) I want to get only assets that have { domain: 'foo' }. Same thing if I try to update, save, delete, and so.
Of course, I can just simply modify the query on each controller since I have accesso to req, but I need to do it every time and I need to remember it for finds, findAndUpdate, save, and soo... sooner or later I'm gonna forget it.
I can define some hooks in Mongoose that will modify the query using a plugin so it adds the domain constraint to the query so I don't have to do it in the controller BUT I don't have the current req object in the Mongoose plugin unless I pass it, and the only way that come to my mind is to abstract the DB methods in the plugin, so in the controller, I do something like this:
model.safeFind(req, query);
And in the plugin I define safeFind like:
safeFind = () => {
const theRealQuery = Object.assign({}, query, { domain: req.locals.domain });
return this.find(query);
}
BUT, in this way, I need to redefine each DB query function (find, findOne, update, save...) and I need to remember to use the safe methods. Then again, I'm going to forget it sooner or later.
Is there a way I can still use the regular Mongoose methods from the controller and have the plugin somehow modify the query for every method using the current req object?

Framework7 and Single Page Application: preload all pages

I'm using Framework7 to build a web application.
https://framework7.io/
I know Framework7 provides routing APIs to navigate through the HTML pages.
https://framework7.io/docs/view.html#router-api-methods-properties
As far as I know the pages are loaded on the fly via AJAX requests. Is it possible to preload all of them and not having any AJAX request after that? I'd like to build a single page application (SPA) in which all the data (HTML pages, CSS and JavaScript code) is loaded at startup
I think theirs no direct solution to do it like your question, since every route will trigger requests when you visit it, but you can try to fix your issue by doing this trick:
Declare global or helper js file.
after declare it, create method/methods inside it which it most be trigger when you visit route, and save the result in global variable (ex: aboutUsDataCache) which can access it in route.
replace all ajax request routes action to method which created for it.
add condition to check if aboutUsDataCache is empty or not, if not empty thats mean we trigger request and has data and we are in SPA, so that we dont to access method again.
Example from real project:
I have main-config.js which is load before routes and has this code:
module.exports.tmpAppCache = {
fullCadaverList: false,
fullImagesList: false,
fullVideosList: false,
fullPdfList: false,
};
and I have ajax-helper.js file which its loaded before routes too and have methods
like this:
export function getFullPdfList() {
// Your ajax request here
}
in routes has this code:
{
path: '/pdf/',
async: function (routeTo, routeFrom, resolve, reject) {
if(globalObject.tmpAppCache.fullPdfList !== false){
resolve(
{
component: pdfPage,
},
{
context: {
data: globalObject.tmpAppCache.fullPdfList
}
}
);
}else{ getFullPdfList()
}
},
},
This example from real project, I try to remove all unwanted code to be something clear so that theres some note:
This example usage WebPack, so that you see import and export some time..
I remove promise from functions to make code example is clear.
since you need to trigger all request at start, you need to call all methods in index route, so that when you go to any page like our example you will see data is cached and request will not trigger.
Good luck

What can I use in a React app as an equivalent of Angular's $http.get

I am looking to make an http request within a React app and am wondering what the best method would be.
I know in Angular you can use $http.get, so something like:
$http.get('API').success(function(data) {...
But what can I use for the same purpose within a React App. Would something like Axios work?
Forgive my ignorance, total newbie here.
checkout window.fetch. It has a very nice API to work with. It is a fetch function is now provided in the global window scope.
if you want to support browser without fetch implemented. try a polyfill like this one from github https://github.com/github/fetch
here is a quick example
// url (required), options (optional)
fetch('/some/url', {
method: 'get'
}).then(function(response) {
if (response.ok) {
return response.json()
}
}).then(function(json) {
console.log(json)
// set your state, your props, your child context do whatever you want
// with the json
// this.setState({ data: json })
}).catch(function(err) {
// Error :(
})
Here a great tutorial
Here is the spec
You can use JQuery library's ajax methods or specific libraries like Superagent. For Superagent just install it with npm, for example npm i superagent --save and make http requests for example:
request
.get('/search')
.end(function(err, res){
// function body
});
Here is complete documentation for it.

How prevent ember-data send request to server?

I've a route which user can pick more options for your account. But when I enter on this route, ember send a GET to my API. How I avoid this since I've the information I need.
I'm using Ember JS 2x.
import Ember from 'ember';
export default Ember.Route.extend({
searchPlaces: Ember.inject.service(),
model() {
return this.store.findAll('user');
},
afterModel(model) {
let token = model.get('token');
let places = model.get('places');
this.set('places', places);
this.set('token', token);
}
});
First, I recommend reading the DS.Store API docs. There are four methods that seem relevant:
findRecord -- returns a Promise, tries memory first, then an API call
findAll -- like findRecord, but for all records of a type
peekRecord -- returns the record if it's in memory already, or null if not; doesn't make an API call
peekAll -- returns an Array of the records of a type that are already in memory
I suspect you want to call store.peekRecord or store.peekAll in your route if you want to avoid the API lookup.
If you access some relationships of that account in "some route" template it might need to lazy-load them and that's why GET request could fire.
If you want to get rid of that request you could override model of some route and make sure you don't use store.find there.

Where to code inorder to override backbone.sync

I want to override backbone.sync i have already asked this but the problem is i don't quite get it. I need to know where to put the codes if i were to override the sync function.
If i put it on the model like this
model = Backbone.Model.extend({ sync:"" });
Then how should i call it? if i were to use the save method. Also i need to change the methodMap of create from POST to PUT. temporarily i resorted to this 'create': 'PUT', actually editing the backbone.js file ( iknow its not good ). Before i forgot i also need to add this
sendAuthentication = function (xhr) {
xhr.setRequestHeader('Authorization', auth)
};
As a beforeSend parameter since my server has authentication. Again where should i do it? Where should i go and put the codes? in my model? in my collection? or in my views? Any help? THank you.
update
Also can i override the sync on my collection? i mean can i have something like this?
collection = Backbone.Collection.extend({ sync:""});
The strategy behind Backbone framework is to make it simple for editing and flexible for every need. So if you look up the source code you'll find out that every method, which calls Backbone.sync in fact calls first "this.sync".
From the Backbone manual you can read :
The sync function may be overriden globally as Backbone.sync, or at a
finer-grained level, by adding a sync function to a Backbone
collection or to an individual model.
So you have two options
Option One - Replacing global Backbone.sync function
If you override the global Backbone.sync you should place your code in your global application file ( actually anywhere you want, but it must be evaluated ( executed ) at your initial javascript loading, to work as expected
// Anywhere you want
Backbone.sync = function(method, collection, options) {
console.log(method, collection options)
}
This will override Backbone.sync and actually will display on your console what is called every time you call collection.fetch, save, delete, etc.
Here you have no default Methodmap, infact you have nothing else except the arguments :
method - which is a string - 'read', 'create', 'delete', 'update'
collection - which is your collection instance which calls the method
options - which has some success, error functions, which you may or may not preserve.
Debug this in your browser, while reading the Backbone source code, it's very easy to understand.
Option Two - Adding to your model/collection sync method
This is used if you wish to use the default Backbone.sync method for every other model/collection, except the one you specifically define :
mySocketModel = Backbone.Model.extend({
sync : function(method, collection, options) {
console.log('socket collection '+this.name+' sync called');
}
});
Partners = new mySocketModel({ name : 'partners' });
Users = new mySocketModel({ name : 'users' });
Log = new Backbone.Collection;
So if you call Partners.fetch() or Users.fetch(), they won't call Backbone.sync anymore, but yor Log.fetch() method will.

Categories

Resources