Is it possible to use $http of AngularJS as stand alone application? - xmlhttprequest

$http is a nice aspect of AngularJS. But can we use it without AngularJS?
For example:
<script src="LIBRARY/http.js"></js>
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});
The intention is to use $http without AngularJS. (Usage example copied from the documentation.)

I haven't come across standalone http package provided by angular but axios is another library that is similar to angularJs http module. Both axios and http are promise based http clients. I'd say using axios would be better than bringing entire angularJs library.
https://github.com/axios/axios
https://www.npmjs.com/package/axios

Related

Get Nuxt inject API alias outside *vue file

As the way of injecting API and call API by nuxt alias like this post
NuxtJS - manage several axios instances
It is working well with Vue file or middleware.
But since I create new folder in src is service for managing API, I can't call alias of API any more.
-src
-plugins
-api.js
-services
-user.js
in file user.js, I use alias to call API but it does not work ($nuxt.$api)
user.js
export default {
async getUser(payload) {
return await $nuxt.$api.get('/user/', {
headers: {
Authorization: `Bearer ${payload}`
}
})
}
}
How can I solve my issue?

Axios in React Native doesn't provide Form-Data headers

I'm trying to upload a file via Axios (Version ^0.26.0) in React Native (Version 0.66.4) with the following code:
const formData = new FormData();
formData.append('image', {
uri: 'aFilePathProvidedByTheImagePicker',
name: 'file.jpg',
type: 'image/jpg'
});
const response = await this.axiosInstance.put('aCustomUrl', formData, {
headers: {
'Content-Type': 'multipart/form-data;',
},
});
But it always fails with the status code 400. I tried the requested endpoint with Postman and it works fine.
After some debugging and comparing the requests from axios and postman I found out that the Content-Length header is missing. Also a boundary in Content-Type isn't provided. See the screenshots below:
Postman:
Reicht Native Debugging:
I also read about the formData.getLengthSync() but in react native it leads to the error formData.getLengthSync is not a function
Does anyone has a solution for this issue?
According to this post downgrading axios to version 0.24.0 works as a workaround.
(for debugging purpose I used the build in fetch-api which works as expected. but I'd prefer using axios for using a shared instance with request and response interceptors)
This issues is solved in Axios Version 0.27.2 (https://github.com/axios/axios/issues/4460#issuecomment-1115163147)
Your code should work but you could try to add content-type to headers
"Content-Type": "multipart/form-data; boundary=" + formData .getBoundary(),

vue integration test with axios and real server calls

Beeing new to vue testing, I'm trying to make an integration test for our Vue SPA with axios & mocha.
I want some of the tests to make real api calls to our server without mocking, to figure out if it really works from the beginning to the end. The server API is a Laravel 7 app with laravel/sanctum and cookie based session authentication.
I can make real axios calls directly in the test file like this:
import authApi from '../../src/components/connections/auth';
describe('AxiosCallTest', () => {
it('makes an axios call', function(done) {
this.timeout(5000);
authApi.get('/sanctum/csrf-cookie').then((response) => {
console.log('response: ', JSON.stringify(response));
done();
}).catch(() => {
done();
});
});
});
// -> response: {"data":"","status":204,"statusText":"No Content","headers":{"cache-control":"no-cache, private"},"config":{"url":"/sanctum/csrf-cookie","method":"get","headers":{"Accept":"application/json","X-Requested-With":"XMLHttpRequest"},"baseURL":"http://testing.backend.vipany.test/api/auth","transformRequest":[null],"transformResponse":[null],"timeout":30000,"withCredentials":true,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"axios-retry":{"retryCount":0,"lastRequestTime":1591774391768}},"request":{"upload":{"_ownerDocument":{"location":{"href":"http://localhost/","origin":"http://localhost","protocol":"http:","host":"localhost","hostname":"localhost","port":"","pathname":"/","search":"","hash":""}}},"_registeredHandlers":{},"_eventHandlers":{}}}
I've read and tried a lot and now have 2 problems:
handling cookies for CSRF Token Cookies and Session Cookies (used for authentication), as on conventional requests the browser handles this out of the box.
waiting on axios calls in vue components, as I can't use mocha's done() function in the components itself, as I did in this example. I can only find examples with mocking requests with moxios or similiar. But I don't want to mock the axios calls.
Does anyone know a good article about these issues or has already solved it?
Thanks a lot
update:
I've found an article to get the cookie out of the axios request and tried it myself to get the X-XSRF-TOKEN out of the response (I've checked it in the browser: HttpOnly: false, secure: false), but it does not work:
console.log('response X-XSRF-TOKEN: ', response.config.headers['X-XSRF-TOKEN']);
// -> undefined
Found out that cypress and nightwatch are the right tools for end-to-end testing (e2).
Didn't know the right terms (e2e or end-to-end testing) and the right tools.
Switched to cypress.io - absolutly great.
vue-cli even has first hand plugins to integrate cypress or nightwatch: https://cli.vuejs.org/core-plugins/e2e-cypress.html

Using Cypress to Test an App That Relies on OAuth

I've inherited a Node.js web app that uses relies on OAuth. Whenever you visit a page the app ensures you've authenticated. Please note, there no Angular, React, Vue, etc here. Each page is straight up HTML.
I want to test this site using Cypress. My problem is, I'm stuck on the initial redirect from the auth provider. Cypress acknowledge OAuth is a challenge.
commands.js
Cypress.Commands.add('login', (credentials) => {
var settings = {
'clientId':'<id>',
'scope':'<scope-list>',
...
};
var body = `client_id=${settings.clientId}&scope=${settings.scope}...`;
var requestOptions = {
method: 'POST',
url: 'https://login.microsoftonline.com/...',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: body
}
cy.request(requestOptions);
});
Then, in my test, I have:
context('Home', () => {
it('Visits Successfully', () => {
cy.login();
cy.title().should('include', 'welcome');
});
});
In the test runner, I see the login POST request is occurring. I confirmed that an access token is being received using a console.log, however, my title is empty. It's like the redirect after OAuth isn't happening in Cypress. However, when I visit the site in the browser, the redirect is happening as expected.
What am I missing?
What you might be missing is confusing between the actual UI flow and the programmatic flow of doing OAuth with a 3rd party website.
What you would want to do is to complete the programmatic login and then send the required parameters to your OAuth callback URL for your app manually in the test code.
an example is given here (though it uses a different grant type it gives you an idea) https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/#Writing-tests-using-Cypress-Login-Command
another issue on the cypress github that deals with a similar problem
https://github.com/cypress-io/cypress/issues/2085
this also might help:
https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/logging-in__single-sign-on/cypress/integration/logging-in-single-sign-on-spec.js

datatables.net ajax outside angular scope does not call the interceptor

Angular CLI: 7.3.3 | Node: 10.7.0 | OS: linux x64 | Angular: 7.2.6
I need server side pagination, sorting and filtering, my table will get 100.000 records easily.
Project example -> https://github.com/sibelly/angular-with-datatablesnet
This example consumes themoviedb API, it's just for testing, that is not my real scenario. Here in this project, I don't activate the server side option as I said is just for testing the calling to my interceptor, just to prove that with ajax directly the interceptor isn't called.
On my real scenario, I have a Laravel API, which has the methods that expect the pagination, sorting and filtering params, because I need it to be done server side to reach a better performance and usability.
When I call the API endpoint using HttpClient, it calls my error.interceptor.ts normally, but the pagination, sorting and filtering information isn't passing to the URL.
So, I concluded that I need to call it via Ajax when I call using the ajax the params are sent as expected.
But what happens is that the user token expire and I need to redirect to the login page again. And this is done using the interceptors of angular, that is not activated when calling using ajax directly because it is outside angular's scope.
To resume, how can I intercept my ajax calling from datatables.net framework in my angular project?
Or is there another way to make the server side pagination, sorting and filtering?
movie.component.ts
ngOnInit() {
//When calling this method the error.interceptor is activated normally
//this.getMostPopularMovies();
//But when I call direct using the AJAX, the interceptor doesn't work
this.dtOptions = {
ajax: {
url: 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=2ed54a614803785fce2d7fe401cc3b21',
params: {
api_key: this.moviedbService.apiKey
},
dataSrc: 'results'
//type: 'GET',
//headers: {"Authorization": 'Bearer ' + JSON.parse(localStorage.getItem('authUser'))["token"]}
},
columns: [
{ data: 'title' },
{ data: 'release_date' }
]
};
}
getMostPopularMovies(){
this.moviedbService.getMostPopularMovies().
subscribe((movies: any) => {
this.moviesList = movies.results;
console.log("====", movies);
}, (error: any) => {
console.error("Erro-> ", error);
});
}
Thanks, guys o/