I have an issue in my app that fetches data by getting it from another website. I want my screen to show the data in real time so if any changes happened on the website, it shows the changes in my app without the need to click on update or do any other action.
I tried to use future but I don't know how to use it. This is my code:
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
class FetchDataAPI {
get(String url, String function, Map<String, String> header) async {
List Response = List();
Response.clear();
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
// Internet connected
try {
var resBody = await http.get(
url,
headers: header,
);
print(resBody.statusCode);
// 200
if (resBody.statusCode == 200) {
Response = [json.decode(resBody.body)];
return Response ;
}
// Not 200
else {
Response = [
{
"exception": false,
"statusCode": resBody.statusCode,
// Body here depend on response post man
"body": json.decode(resBody.body),
"message": null
}
];
return Response;
}
} catch (e) {
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": e.toString()
}
];
return Response;
}
} else {
// Internet not connected
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": "No internet conected."
}
];
return Response;
}
} on SocketException catch (e) {
Response = [
{
"exception": true,
"statusCode": null,
"body": null,
"message": "No internet conected."
}
];
return Response;
}
}
}
You should use Streams, alongside StreamBuilder
Related
I am writing a dotnet core web api
the POST method on controller looks like :
// POST: api/SurveyUserResponses
[HttpPost]
public async Task<IActionResult> PostSurveyUserResponse([FromBody] List<SurveyUserResponse> surveyUserResponse)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.SurveyUserResponse.AddRange(surveyUserResponse);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (SurveyUserResponseExists(surveyUserResponse[0].UserId))
{
return new StatusCodeResult(StatusCodes.Status409Conflict);
}
else
{
throw;
}
}
return new StatusCodeResult(StatusCodes.Status201Created);
}
This works fine 201 created when I use Postman to send this json :
[
{
"userId": 1,
"qId": 1,
"optionId": 0,
"response": "Suryansh",
"surveyCreatorOptions": null,
"user": null
},
{
"userId": 1,
"qId": 2,
"optionId": 0,
"response": "suryansh",
"surveyCreatorOptions": null,
"user": null
}
]
But when I use $.post("https://localhost:44366/api/surveyuserresponses/postsurveyuserresponse",JSON.stringify(jsonArr)); Chrome console shows 400(Bad Request)
For figuring out the problem I even tried copying the form data and sent it through Postman it works just fine.
I can't figure out the issue.
But when I use $.post("https://localhost:44366/api/surveyuserresponse/postsurveyuserresponse",JSON.stringify(jsonArr));
Since your server expects a payload of JSON, you need specify a header of Content-Type for the request:
$.ajax({
type: "POST",
url: "https://localhost:44366/api/surveyuserresponses/postsurveyuserresponse",
contentType: "application/json",,
data: JSON.stringify(jsonArr),
success: function(result){ /*...*/ }
});
I can't seem to find any headers in the response from my express back-end in nativescript angular response,i previously had res.header but wasn't any different.
Express back-end :
router.post('/login', (req, res) => {
User.findOne({
email: req.body.email
})
.then((foundUser) => {
if (!foundUser) res.send('Email Or Password Is Invalid');
else {
bcrypt.compare(req.body.password, foundUser.password) //compare hashed with db string
.then((validPassword) => {
if (!validPassword) res.send('Invalid Email Or Password').status(400);
else {
const token = jwt.sign({
_userID: foundUser.userID
}, config.get('jwtPrivateKey'));
res.set({
'content-type': 'application/json',
'x-auth-token': token
}).send('Logged In').status(200);
}
});
}
}).catch((err) => {
res.send('Oops something went wrong').status(500);
});
});
Nativescript Http:
onLogin(){
console.log(this.textScrap());
this.registartion.Login(this.textScrap())
.subscribe((response) => {
console.log(response);
},(err) => {
console.log(err);
},() => {
// this.router.navigateByUrl() Navigate to homePage when ready
})
}
Then I end up with this response but no header included
{
JS: "headers": {
JS: "normalizedNames": {},
JS: "lazyUpdate": null,
JS: "headers": {}
JS: },
JS: "status": 200,
JS: "statusText": "Unknown Error",
JS: "url": null,
JS: "ok": false,
JS: "name": "HttpErrorResponse",
JS: "message": "Http failure during parsing for (unknown url)",
JS: "error": {}
JS: }
I had a similar issue in NativeScript using Angular6 (and 7), and it turned out to be the Angular HttpClient rejecting empty responses with a status code of 200 instead of 204 (no content). The log showed the same message that you receive.
Even though your server code seems to send a non-empty response on successful logins ('Logged in'), you can try to add an Interceptor in your Angular appplication
to inspect the error further.
In my case I added an Interceptor which sets the body to null in case the HttpClient encounters an error and the status code indicates a successful response:
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Injectable } from '#angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpResponse,
HttpEvent,
HttpErrorResponse
} from '#angular/common/http';
#Injectable()
export class EmptyResponseBodyErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable> {
return next.handle(req).pipe(
catchError((err: HttpErrorResponse, caught: Observable>) => {
if (err.status >= 200 && err.status < 300) {
const res = new HttpResponse({
body: null,
headers: err.headers,
status: err.status,
statusText: err.statusText,
url: err.url
});
return of(res);
}
throw err;
}
));
}
}
Add it to providers in your app.module.ts:
{ provide: HTTP_INTERCEPTORS, useClass: EmptyResponseBodyErrorInterceptor, multi: true },
I did not experience the same issue when running this in Chrome, Firefox or Safari, though - only in NativeScript (both Android and iOS).
I have an Alexa Skill that tries to read the contents from a file stored in S3. The test event for the Lambda function for Alexa Start Session is successful. I understand that there is something wrong with my CompletedMyIntentHandler but I can't quite seem to figure it out. Any help on it is much appreciated. The lambda function takes help from https://github.com/alexa/alexa-cookbook/blob/master/aws/Amazon-S3/read/. Find my Lambda function below;
const Alexa = require('ask-sdk');
// 1. Text strings =====================================================================================================
// Modify these strings and messages to change the behavior of your Lambda function
const helpOutput = 'You can demonstrate the S3 Storage read capability by saying "Hello".';
const helpReprompt = 'Try saying "Hello World".';
var myBucket = 'jailalita'; // replace with your own bucket name!
var myObject = 'hello.txt'; // replace with your own file name!
// 2. Intent Handlers =============================================
const CompletedMyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'MyIntent';
},
handle(handlerInput) {
console.log('My Intent - handle');
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = MyIntent();
return responseBuilder
.speak(speechOutput)
.getResponse();
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
return responseBuilder
.speak(helpOutput)
.reprompt(helpReprompt)
.getResponse();
},
};
const CancelStopHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && (request.intent.name === 'AMAZON.CancelIntent' || request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = 'Okay, talk to you later! ';
return responseBuilder
.speak(speechOutput)
.withShouldEndSession(true)
.getResponse();
},
};
const SessionEndedHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
const request = handlerInput.requestEnvelope.request;
console.log(`Original Request was: ${JSON.stringify(request, null, 2)}`);
console.log(`Error handled: ${error}`);
return handlerInput.responseBuilder
.speak('Sorry, I can not understand the command. Please say again.')
.reprompt('Sorry, I can not understand the command. Please say again.')
.getResponse();
},
};
// 3. Helper Function =================================================================================================
function MyIntent() {
var myParams = {
Bucket: myBucket,
Key: myObject
};
S3read(myParams, myResult => {
console.log("sent : " + JSON.stringify(myParams));
console.log("received : " + myResult);
var speech = this.response.speak('The S 3 file says, ' + myResult );
return speech;
}
);
}
function S3read(params, callback) {
// call AWS S3
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
s3.getObject(params, function(err, data) {
if(err) { console.log(err, err.stack); }
else {
var fileText = data.Body.toString(); // this is the complete file contents
callback(fileText);
}
});
}
// 4. Exports handler function and setup ===================================================
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
//LaunchRequestHandler,
CompletedMyIntentHandler,
HelpHandler,
CancelStopHandler,
SessionEndedHandler,
)
.addErrorHandlers(ErrorHandler)
.lambda();
JSON Input
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.e6f74d95-8d55-4aac-ade0-dd4ff4ed4f04",
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
},
"device": {
"deviceId": "amzn1.ask.device.AETD2DDUWNTWA5BNNDFHCRT26SLOZUTZUFJ5P3OEQGDCWWDSFWPKNONGMT4KZAJPUB6ZRD3YVCDEVFAGPLXHVP6XESWS6BKEYZHZRXT25QNK2RTFNUG4PKD347P5DAWE2H4WQLGTQVLNQ5JNFGHFUSUC3X7Q",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLjVlZGQ0N2JjLTUyNWQtNGVmNC05YjZlLWE4M2E3ZTc5NzQ0ZiIsImV4cCI6MTUzMDUxMzU2NCwiaWF0IjoxNTMwNTA5OTY0LCJuYmYiOjE1MzA1MDk5NjQsInByaXZhdGVDbGFpbXMiOnsiY29uc2VudFRva2VuIjpudWxsLCJkZXZpY2VJZCI6ImFtem4xLmFzay5kZXZpY2UuQUVURDJERFVXTlRXQTVCTk5ERkhDUlQyNlNMT1pVVFpVRko1UDNPRVFHRENXV0RTRldQS05PTkdNVDRLWkFKUFVCNlpSRDNZVkNERVZGQUdQTFhIVlA2WEVTV1M2QktFWVpIWlJYVDI1UU5LMlJURk5VRzRQS0QzNDdQNURBV0UySDRXUUxHVFFWTE5RNUpORkdIRlVTVUMzWDdRIiwidXNlcklkIjoiYW16bjEuYXNrLmFjY291bnQuQUY0U0xSSzVUQzRTRFNITDdMR0sySUI2U01YQ1BHUzdZNllLWUxQREdXUkU3Q0EzSzZNQ0tWVlVXMk9GTVZDV0pGWFpEUUJTWVk1WjJSWFpXUUFKTERDTVIzU1hZQ1ZBN1pBUkRSTlFYQTNUWEJNNElMUDc3RktOT080TUNWUExXSElYVzNRTlpDUllQRFE3Q0NCUDZRVDdHTVRCTVFYMkJWQ05TMjJTWkw0TUM2V0I3R0RTNDRYTjJES0dKUUJNR0lEUTNPN1JCWUQ2R0FJIn19.Fc-aAcaf4qTgf489cQsZ44KTq-yZ-xMJCBenq9DbpppkMgSscF0NodGYTK967AcGblwqOFqcwIC1PvGmISER9oDH5TIhKF1kLsTimRHRKsttElRl7FIEvki-sKLD4VTeStTKM-w5laBm6urAzlCXpJySU-InVH5_qE0M5LHnLZRrE_qy7EmIq2vsrq2Cekve-gQ3Y3ImW3_0b7ikg6gwO6si-O0IxXO6hxS5sTuQH4f4aRybHVO3jflHD7g7pGPFzfkpc_tg6KFkhFv6CMvkx25A2u7iO7vVQpMHdj-_2ZM0ZmO9JuP-v7ydKYT_1IDjfpZKfvgIGyYsNfCPDY5F2Q"
}
},
"request": {
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.12ef23e3-a7e5-48a4-90f9-de9c253f72b9",
"timestamp": "2018-07-02T05:39:24Z",
"locale": "en-US",
"shouldLinkResultBeReturned": false
}
}
JSON Output
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
}
},
"shouldEndSession": false
},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.0 Node/v8.10.0"
}
}
JSON Editor
{
"interactionModel": {
"languageModel": {
"invocationName": "hello world",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "MyIntent",
"slots": [],
"samples": [
"hello"
]
}
],
"types": []
}
}
}
You can't build your response and return inside the S3Read function as it's an async call to an external service. You need to wait for that call using async/await and once you get a value then craft the response and return.
I get the responses from the server in the following format.
{
"Success":true,
"StatusCode":"000",
"Result":[
{
"Id":"1",
"Text":"Cash"
},
{
"Id":"1",
"Text":"Check"
},
{
"Id":"3",
"Text":"Bank"
}
],
"Error":null
}
When the responses is success. i.e "Success":true,
I wanted to return only the Result part of the responses, from the interceptor.
In interceptor i have the following implementation.
Vue.http.interceptors.push(function (request, next) {
this.$Progress.start()
next(function (response) {
if (!response.body.Success) {
this.$toastr('error', response.body.Error.Message)
return false;
}
else{
this.$Progress.finish()
}
})
})
Currently i am using the separate services to fetch the information from the response body, when ever the request is made to the server.
Currently what i am doing is.
var promises = [];
promises.push(ListService.getStateList());
promises.push(ListService.getById("address/city/get/" + to.params.id));
Promise.all(promises).then(response => {
next(p => {
p.StateCollection = p.getResultData(response[0].body, "array");
p.vModel = p.getResultData(response[1].body, "singleobject");
});
});
getResultData
getResultData(data, item) {
if (data.Success) {
return data.Result;
} else {
if (item == 'array'||item == 'list') {
return [];
} else {
return {};
}
}
},
Is it possible to return only the Result part of responses from the interceptor itself?
I don't want to call the getResultData method, as i am doing currently to fetch the Result from the responses.
I wanted to bind the responses to object directly.
like Examples: p.vModel= response. no need to fetch the information from the body.
I am writing a test for webclient viewmodel in Qunit and used Mockjax for moking ajax request, but it seems i am doing something wrong while moking, please help me to solve the following problem.
function WebmailViewModel() {
// Data
var self = this;
self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenMailData = ko.observable();
// Behaviours
self.goToFolder = function(folder) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, self.chosenMailData);
};
self.goToFolder('Inbox');
};
$(function() {
ko.applyBindings(new WebmailViewModel());
});
test("web mail client test", function() {
stop(2);
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
start();
}
});
vm.goToFolder('Inbox');
setTimeout(function() {
deepEqual(vm.chosenFolderData,returnedData, "Two objects can be the same in value" );
start();
}, 150);
});
Test Result:
Two objects can be the same in valueExpected: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
}
Result: function c( ){
[code]
}
Diff: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
function c( ){
[code]
}
Source: at Anonymous function (file:///C:/Users/dasssdeb/Desktop/JS%20Tests/QUnit/tests/tests.js:174:8)
I belive issue is with moking the ajax request. please help me with your valuable experience.
Your mockjax setup must come before your source code. In the code above you initialize the WebmailViewModel (which performs ajax requests) before you set up the mockjax request handler. Try structuring things like this instead:
// SOURCE CODE
// in your source code you will need to have a callback for your WebmailViewModel method arguments...
function WebmailViewModel() {
// ...
// Behaviours
self.goToFolder = function(folder, callback) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
callback(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, function(returnedData) {
self.chosenMailData(returnedData);
callback(returnedData);
});
};
};
Now you can create your test code with callbacks when they finish to hook your assertions into...
// TEST CODE
// Set up the request handler first...
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
}
});
// then create your test...
test("web mail client test", function() {
stop();
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
vm.goToFolder('Inbox', function(returnedData) {
// this is the callback for when going to the folder finishes...
deepEqual(vm.chosenFolderData, returnedData, "Two objects can be the same in value" );
start();
});
});