Below is my code and i am basically trying to send csv and xlxs files using my app. Although, everything looks right to me, i still cannot process and send the file to my backend. When i send the file to the backend, i get a response from the backend as "No file uploaded" although it works fine using postman. What have i missed in my code?
File Component
export class FileUploadComponent {
constructor(private service:FileUploadService) {
this.service.progress$.subscribe(
data => {
console.log('progress = '+data);
});
}
onChange(event) {
console.log('onChange');
let files = event.target.files;
console.log(files);
this.service.makeFileRequest('http://localhost:9000/api/v1/fileUpload/country', [], files).subscribe(() => {
console.log('sent');
});
}
}
FileService
export class FileUploadService {
public progress$;
public progressObserver;
public progress : number;
constructor (private auth:AuthenticationService) {
this.progress$ = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
makeFileRequest (url: string, params: string[], files: File[]) {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append('uploads', files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader('Authorization', 'Bearer ' + this.auth.token);
xhr.send(formData);
});
}
}
Related
I am using an opensource react project and getting the following error.
does not provide an export named 'default'
Here is the .js file causing the issue.
import { RevAiStreamingClient, AudioConfig } from 'revai-node-sdk';
module.exports = class StreamingClient {
constructor(accessToken, io) {
console.log('Loading Streaming Client');
this.accessToken = accessToken;
this.io = io;
}
start() {
this.revAiStreamingClient = new RevAiStreamingClient(this.accessToken, new AudioConfig('audio/x-wav'));
this.revAiStreamingClient.on('close', (code, reason) => {
console.log(`Connection closed, ${code}: ${reason}`);
});
this.revAiStreamingClient.on('httpResponse', (code) => {
console.log(`Streaming client received http response with code: ${code}`);
});
this.revAiStreamingClient.on('connectFailed', (error) => {
console.log(`Connection failed with error: ${error}`);
});
this.revAiStreamingClient.on('connect', (connectionMessage) => {
console.log(`Connected with job id: ${connectionMessage.id}`);
this.io.emit('streaming-connected', connectionMessage);
});
this.revStream = this.revAiStreamingClient.start();
this.revStream.on('data', (data) => {
this.io.emit('transcript', data);
});
}
end() {
this.revStream = null;
this.revAiStreamingClient.end();
}
stream(data) {
console.log('streaming data ....');
this.revStream && this.revStream.write(data);
}
};
UPDATE:
Fixed it.
import { RevAiStreamingClient, AudioConfig } from 'revai-node-sdk';
class StreamingClient {
constructor(accessToken, io) {
console.log('Loading Streaming Client');
this.accessToken = accessToken;
this.io = io;
}
start() {
this.revAiStreamingClient = new RevAiStreamingClient(this.accessToken, new AudioConfig('audio/x-wav'));
this.revAiStreamingClient.on('close', (code, reason) => {
console.log(`Connection closed, ${code}: ${reason}`);
});
this.revAiStreamingClient.on('httpResponse', (code) => {
console.log(`Streaming client received http response with code: ${code}`);
});
this.revAiStreamingClient.on('connectFailed', (error) => {
console.log(`Connection failed with error: ${error}`);
});
this.revAiStreamingClient.on('connect', (connectionMessage) => {
console.log(`Connected with job id: ${connectionMessage.id}`);
this.io.emit('streaming-connected', connectionMessage);
});
this.revStream = this.revAiStreamingClient.start();
this.revStream.on('data', (data) => {
this.io.emit('transcript', data);
});
}
end() {
this.revStream = null;
this.revAiStreamingClient.end();
}
stream(data) {
console.log('streaming data ....');
this.revStream && this.revStream.write(data);
}
}
export default StreamingClient;
I need to see more of the error message to understand but best guess is that somewhere in your code it says export default instead of export default insert component name.
I have used the loading controller as a separate service, and called the present and dismiss methods inside http interceptor, but even after the request is released by interceptor and dismiss method is called, loading modal keep loading in UI,
interceptor code,
removeRequest(req: HttpRequest<any>) {
const i = this.requests.indexOf(req);
if (i >= 0) {
this.requests.splice(i, 1);
}
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loadingCtrl.present();
this.requests.push(request);
return Observable.create(observer => {
const subscription = next.handle(request)
.subscribe(
event => {
if (event instanceof HttpResponse) {
this.removeRequest(request);
observer.next(event);
}
},
err => {
this.removeRequest(request);
observer.error(err);
this.toastor.presentToast(err.message);
},
() => {
this.removeRequest(request);
observer.complete();
this.loadingCtrl.dismiss();
});
return () => {
this.removeRequest(request);
subscription.unsubscribe();
};
});
}
}
loader controller service
export class LoadingService {
isLoading: boolean = false;
i = 0;
constructor(public loadingController: LoadingController) {}
async present() {
console.log('instance present ', this.i);
this.isLoading = true;
return await this.loadingController
.create({
message: 'Loading.......',
backdropDismiss: true,
})
.then((loader) => {
loader.present().then(() => {
if (!this.isLoading) {
loader.dismiss().then(() => {});
}
});
});
this.i = this.i + 1;
}
async dismiss() {
console.log('instance dismiss', this.i);
this.isLoading = false;
await this.loadingController.getTop().then((hasLoading) => {
if (hasLoading) {
return this.loadingController.dismiss().then(() => {});
}
});
this.i = this.i + 1;
}
}
Any idea why this happens ?
I had a similar problem with Ionic-React. In my case the dismiss executed before the present finished. Both are asynchronous, you should simply await present.
I am trying to get Display Name getUserinfo() based on a User ID getList()
I have attempted
to use a variable to catch the data and feed to getList().
to use state variables to setState and pass data to getList(). but it seems State is asynchronous, so it failed
Problem: why my getUserinfo() cannot return a value for getList() to use ?
private getUserinfo(userid: number) {
var result;
let url;
url = `/_api/web/GetUserById(${userid})`;
const opt: ISPHttpClientOptions = {
headers: { "Content-Type": "application/json;odata=verbose" }
};
this.props.spHttpClient
.get(
this.props.context.pageContext.web.absoluteUrl + url,
SPHttpClient.configurations.v1,
opt
)
.then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
if (json.Title) {
let name = json.Title;
let email = json.Email;
let issiteadmin = json.IsSiteAdmin;
//debugger;
return name; // this has value but it returns nothing in another function I called
}
});
});
}
private getList() {
this.state.data.length = 0;
const qurl =
"/_api/web/lists/getbytitle('list')/items?$select=*&$orderby=Modified desc";
const opt: ISPHttpClientOptions = {
headers: { "Content-Type": "application/json;odata=verbose" }
};
this.props.spHttpClient
.get(
this.props.context.pageContext.web.absoluteUrl + qurl,
SPHttpClient.configurations.v1,
opt
)
.then((response: SPHttpClientResponse) => {
response.json().then((json: any) => {
for (let i = 0; i < json.value.length; i++) {
let authorid = json.value[i].AuthorId;
let editorid = json.value[i].Editorid;
let Authorname = this.getUserinfo(authorid);
let Editorname = this.getUserinfo(editorid);
debugger;
this.setState({
data: [
...this.state.data,
{
Authorname,
Editorname
}
]
});
}
});
});
}
Because you have not returned anything from getUserInfo, you had just called this.props.spHttpClient.get() without returning its value, for instance:
private getUserinfo(userid: number) {
...
return this.props.spHttpClient.get( ... )
.then((response: SPHttpClientResponse) => {
return response.json().then((json: any) => {
if (json.Title) {
let name = json.Title;
let email = json.Email;
let issiteadmin = json.IsSiteAdmin;
return name; // this has value but it returns nothing in another function I called
}
});
});
}
This way, when you call this.getUserinfo(authorid) you will get a promise and you can use its value as follows:
this.getUserinfo(authorid).then( name => {
// use its name
});
This is how you would write it using async/await which improves the readability
private async getUserinfo(userid: number) {
var result;
let url;
url = `/_api/web/GetUserById(${userid})`;
const opt: ISPHttpClientOptions = {
headers: { "Content-Type": "application/json;odata=verbose" }
};
const response: SPHttpClientResponse = await this.props.spHttpClient
.get(
this.props.context.pageContext.web.absoluteUrl + url,
SPHttpClient.configurations.v1,
opt
)
const json = await response.json();
if (json.Title) {
let name = json.Title;
let email = json.Email;
let issiteadmin = json.IsSiteAdmin;
//debugger;
return name; // this has value but it returns nothing in another function I called
}
}
You can aply the same style to getList
How can i add authentication token to the file upload service? When i login in my application, i am able to retrieve the token from the backend but i am having a hard time as to how to add it the to file service. When i try to upload a file, it get an error saying "token_not_provided". As it is in my service, i have added the authentication token in my header so whenever i make a request, the server is aware of the user at hand. But with the file submission, i have no idea of how to append the authentication token to the file service
#Component({
providers:[AuthenticationService]
})
#Injectable()
export class FileUploadService {
public progress$;
public progressObserver;
public progress : number;
public token: string;
public headers:string;
constructor (private auth:AuthenticationService) {
this.progress$ = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
makeFileRequest (url: string, params: string[], files: File[]) {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};
xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);
this.progressObserver.next(this.progress);
};
xhr.open('POST', url, true);
xhr.setRequestHeader(this.headers, this.auth.token);//modified
xhr.send(formData);
});
}
}
//service
updateFood(food:any) {
const body = JSON.stringify(food);
const headers = new Headers({ 'Authorization': 'Bearer ' + this.authenticationService.token });
return this.http.put('http://localhost:9000/, body, {headers: headers})
.map((data:Response) => data.json());
}
Somewhere between your xhr.open and xhr.close you can append headers
xhr.setRequestHeader(header, value);
See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader for more detailed documentation
I want to develop a file configuration of json and it is called with http get the constructor and return the value I want the config file to another component. But when return gives me value undefined.
My Config.json
[ {"urlServer": "http://localhost:56877"}]
My Config.Service
export class configService
{
url: string;
constructor(public _http: Http)
{
let injector = Injector.resolveAndCreate([loggerService]);
let logger = injector.get(loggerService);
try {
return this._http.get('/app/config.json',
{
headers: contentHeaders
})
.map((res: any) =>
{
let data = <configModel>res.json();
this.url = data.urlServer;
JSON.stringify(this.url);
});
}
catch (ex) {
logger.registarErros('configService', ex);
}
}
returnConfig()
{
return this.url;
}
Now my other Component
constructor(public _http: Http, public config: configService)
{
this.token = sessionStorage.getItem('token');
this.username = sessionStorage.getItem('username');
}
login(username: String, password: String)
{
let injector = Injector.resolveAndCreate([loggerService]);
let logger = injector.get(loggerService);
try
{
alert(this.config.url);
return this._http.post('http://localhost:56877/api/Login/EfectuaLogin', JSON.stringify({ username, password }),
{
headers: contentHeaders
})
.map((res: any) =>
{
let data = <authLoginModel>res.json();
this.token = data.token;
this.username = data.nome;
sessionStorage.setItem('token', this.token);
sessionStorage.setItem('username', this.username);
return Observable.of('authObservable');
});
}
catch (ex) {
logger.registarErros('authentication', ex);
}
}
I no longer know how to solve the problem, I need your help, I'm not very experienced with Angular 2.
Thanks very much.
The problem here is that the config is load asynchronously. You could use something like that leveraging the flatMap operator:
#Injectable()
export class ConfigService {
urlServer:string;
constructor(public _http: Http) {
}
getConfig() {
if (this.urlServer) {
return Observable.of(this.urlServer);
}
return this._http.get('/app/config.json', {
headers: contentHeaders
})
.map((res: any) => {
let data = <configModel>res.json();
return data.urlServer;
}).do(urlServer => {
this.urlServer = urlServer;
});
}
}
and in your component:
login(username: String, password: String) {
return this.configService.getConfig().flatMap(urlServer => {
this._http.post('http://localhost:56877/api/Login/EfectuaLogin',
JSON.stringify({ username, password }),
{
headers: contentHeaders
})
.map((res: any) =>
{
let data = <authLoginModel>res.json();
this.token = data.token;
this.username = data.nome;
sessionStorage.setItem('token', this.token);
sessionStorage.setItem('username', this.username);
return data; // or something else
});
}
});
}
Another approach would be boostrap asynchronously after having loaded the configuration:
var app = platform(BROWSER_PROVIDERS)
.application([BROWSER_APP_PROVIDERS, appProviders]);
service.getConfig().flatMap((url) => {
var configProvider = new Provider('urlServer', { useValue: urlServer});
return app.bootstrap(appComponentType, [ configProvider ]);
}).toPromise();
See this question for the second approach:
angular2 bootstrap with data from ajax call(s)
You can go further by mixing the last approach with a CustomRequestOptions:
import {BaseRequestOptions, RequestOptions, RequestOptionsArgs} from 'angular2/http';
export class CustomRequestOptions extends BaseRequestOptions {
merge(options?:RequestOptionsArgs):RequestOptions {
options.url = 'http://10.7.18.21:8080/api' + options.url;
return super.merge(options);
}
}
See this question:
Angular 2 - global variable for all components