Axios customizable base URL - axios

Is there any way to make a customizable URL with axios? For example, I've created an axios instance:
import axios from 'axios';
const instance = axios.create({
baseURL: 'localhost:8001/**test**/service/**test**/method' ,
});
export default instance;
Now I want to use this instance in many places in my project, but when I call this instance I'd like to change both **test** with params I pass to it.
Is that possible?

Make a function
function createAxios(string) {
return axios.create({baseUrl: `localhost:8001/${string}/service/**test**/method`})
}
So when you want it another place, just write
const instance = createAxios("test")

Related

Using angular2-sails module for realtime communication using sockets

I would like to use sails.io.js with angular5, so I used angular2-sails module. I managed to connect angular to sails but I didn't manage to retrieve the events from sails.js, for example when a new document is created in database. Is there something to configure sails side ? I used this.sailsService.on("user").subscribe(data => console.log("event on user")). The get and post methods are perfectly working. Sails side I put
ioclient: require('socket.io-client')('http://localhost:1337'),
io: require('sails.io.js'),
In config/http.js, instead of
var io = require('sails.io.js')( require('socket.io-client') );
because else sails cannot load
I didn't write anything in config/socket.js
angular2-sails module is deprecated so I used the io variable from sails.io.js using a service :
import {Injectable} from '#angular/core';
function _window(): any {
// return the global native browser window object
return window;
}
#Injectable()
export class SocketService {
get ioSails(): any {
return _window().io;
}
}

call a global constant into service Angular2

In my Angular2 application I use services which call a REST API like this from http://localhost:22222/app/webresources/entity..
I want to set part of this URL just one time and call it from the services which I need.
I think I need to create an Interface which has a constant URL, but is it possible to implement this in a service?
I put something like this in my data-access.service.ts:
export const API_URL: string = "http://my.api.com/"
It's useful because I can use it in my service methods:
getStuff(): Observable<Stuff> {
return this.http.get(API_URL + `/path/to/stuff/with/${parameters}`)
.map(response => response.json())
.catch(this.logError);
Or later in a template somewhere:
import { API_URL } from '../shared/data-access.service';
#Component({
template: 'Link to stuff'
})
export class MyComponent {
api: string = API_URL;
…
}

Modify routing in Sails to use something else than id?

I have a web app which talks to my backend node.js+sails app through a socket.
Default routes for sockets use id. As example
io.socket.get('/chatroom/5')
My app doesn't authenticate users and as result I want id's to be random, so nobody can guess it. However, id's are generated by mongoDB and aren't that random.
As result, I want to use some other field (a.e. "randomId") and update routing for this model to use this field instead of id.
What's the best way to do it?
P.S. It looks like I have to use policies, but still struggling to figure out what should I do exactly.
You aren't forced to use the default blueprint routes in your app; you can always override them with custom controller methods or turn them off entirely.
The GET /chatroom/:id method automatically routes to the find action of your ChatroomController.js file. If you don't have a custom action, the blueprint action is used. So in your case, you could define something like the following in ChatroomController.js:
find: function (req, res) {
// Get the id parameter from the route
var id = req.param('id');
// Use it to look up a different field
Chatroom.find({randomId: id}).exec(function(err, chatrooms) {
if (err) {return res.serverError(err);}
// Subscribe to these rooms (optional)
Chatroom.subscribe(req, chatrooms);
// Return the room records
return res.json(chatrooms);
});
}
If you don't like the name find or the param id, you can set your own route in config/routes.js:
"GET /chatroom/:randomid": "ChatroomController.myFindActionName"
Also, re:
Default routes for sockets use id.
those routes aren't just for sockets--they respond to regular HTTP requests as well!
I created a policy. This policy converts randomId (which is passed as :id) to real id and saves it in req.options.id (which Sails will pick up).
module.exports = function(req, res, next) {
var Model = req._sails.models[req.options.model];
var randomId = req.params.all()['id'];
Model.findOne().where({ randomId: randomId }).exec(function(err, record) {
req.options.id = record.id;
return next();
});
};
And I apply this policy to findOne and update actions of my controller:
ChatRoomController: {
findOne : 'useRandomId',
update : 'useRandomId'
}

Play Framework redirect not working in Safari

I'm attempting to query Solr from Angular and routing the request through a Play Controller for security and using Play redirect to forward the request to Solr.
This seems to be working on Chrome but not on Safari/Firefox.
Angular ajax request
var solrUrl = '/solr';
storesFactory.getAdvancedMessages = function (searchCriteria, searchType) {
var filterQuery = solrQueryComposer(searchCriteria);
$log.warn(filterQuery);
return $http({
method: 'GET',
url: solrUrl,
params: { 'q': '*',
'fq': filterQuery,
'rows': 30,
'wt': 'json'}
}).
then(function(data, status, headers, config) {
$log.debug(data.data.response.docs);
return data.data.response.docs;
},
function(error){
$log.error(error.message);
});
Play Controller
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Security;
#Security.Authenticated(Secured.class)
public class SolrController extends Controller {
private static String solrUrl = "http://whatever.com:5185/solr/select/";
private static String queryPart = "";
public static Result forward(){
queryPart = request().uri().substring(5);
System.out.println(queryPart);
return seeOther(solrUrl+queryPart);
}
}
Play Route
GET /solr controllers.SolrController.forward()
First of all, I'd like to clarify what you're doing.
Play is not forwarding anything here, it's sending a redirect to the client, asking to fetch another URL. The client will send a request, receive a redirect, and send another request.
Which means:
this controller is not "forwarding" anything. It's just tells the client to go somewhere else. ("seeOther", the name speaks for itself).
It's not secure at all. Anyone knowing solr's URL could just query it directly.
since the query is performed by the client, it may be stopped by the cross-domain security policy.
Moreover, There's a HUGE race condition waiting to happen in your code. solrUrl and queryPart are static, therefore shared by all threads, therefore shared by all clients!!
There's absolutely no reason for queryPart to be static, and actually, there's absolutely no reason for it to be in this scope. This variable should be defined in the method body.
I'd also like to point out that request().uri().substring(5) is very brittle and is going to break if you change the URL in the route file.
In return seeOther(solrUrl+queryPart), queryPart arguments keys and values should also be URLencoded.

Angular.js Dynamic Binding when posting to restful server

I am somewhat confused of the way to achieve the two-way data binding when posting to my server.
I defined my resource like this:
angular.module('todoServices', ['ngResource']).
factory('Todo', function($resource){
return $resource('api/v1-0/todos/:todoId', {}, {
query: {method: 'GET', params:{todoId:''}, isArray: true},
save: {method: 'POST', isArray: true}
});
})
and I pass the Todo resource to my controller as a dependency.
Then in my controller I have a method to add a new Todo item to my list:
$scope.addTodo = function() {
var savedModel = new Todo();
savedModel.title = $scope.title;
savedModel.description = $scope.description,
//...
savedModel.$save();
$scope.todos.push(savedModel);
}
This works as far as my todo appears in the list, the call to the server works and the item is added in my database.
However, since when I push it to my list, it does not have an ID, yet. The ID is generated by an auto-increment ID in my MySQL database.
My server returns the object in JSON format, so I assume, I have to specify some sort of callback function to get the data-binding to work?
What exactly do I need to do, so my todo which has been added is updated with the correct ID once my server returns the data?
Simply assign the returned object to the savedModel object. Since calls to resources are asynchronous and return a promise, you should use the success function this way:
savedModel.$save(
function success(savedModel) {
$scope.todos.push(savedModel);
});
By the way, check the isArray property of the save method, normally should be false.