Flutter: Get "raw" html document from website - html

I am fairly new to (flutter) development and I have a question:
There is this website, and I would like to display the content in an app. As far as I understood the website, it is an server-site html render. Since there are no API's (atleast I didn't find them) which I can use to read the data, I wanted to get the whole html document and parse all of the "interesting" data out.
Do you have any idea how I get the html document so that I can start parsing?
Or is there a more elegant solution to my problem?
Info: I don't want to make a html render, I have build my own UI and just want to insert specific data
Thanks a lot in advance!

I've just tested an http.get request on Flutter to the url you specified and works well. I used this package to make the get request, I defined an async funcion to make the request and in the main function of a Flutter app I call that function:
//This import the package
import 'package:http/http.dart' as http;
//...
//Here comes code of Flutter
//...
//Now I define the async function to make the request
void makeRequest() async{
var response = await http.get('https://speiseplan.app.itelligence.org/');
//If the http request is successful the statusCode will be 200
if(response.statusCode == 200){
String htmlToParse = response.body;
print(htmlToParse);
}
}
//...
//Here comes more Flutter code
//...
main(){
makeRequest();
}
This will print the html you want, as String and now you can parse it as you want.

Related

How can I use the JSON value obtained from a function in a different function? (Might be clearer with explanation below)

So I have a pretty normal eventListener that listens to the incoming events.
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
It goes to the handleRequest, which does certain different tasks depending on the request.url.
async function handleRequest (request) {
var url = new URL(request.url);
if (url.pathname === '[some-domain-name]/[some-link]') {
var jsonResult = handleJSON();
return jsonResult;
} else {
return handleHTML();
}
The handleJSON() and the handleHTML() are two additional functions that I have set up. What I essentially want to do is add one more if condition that has the criteria based on the response from handleJSON(), i.e., if jsonResult = [somevalidvalue] run handleHMTL() else respond with "You haven't accessed /[some-link] yet.
So to summarize, if we go to [some-domain-name] it should respond with the sentence. Then once we access /[some-link] we get some kind of value in jsonResult AFTER WHICH if we go back to [some-domain-name] it should hit with the response from handleHTML(). Also if possible, I'd like to know how can I pass the value from jsonResult in to our handleHTML() function. This is the result in the jsonResult.
const body = JSON.stringify(links, null, 2)
return new Response(body, init)
I'm sorry if the information sounds too long and stretched out. I haven't used Cloudflare's worker before and I've been trying to figure out the little stuff of what goes where and what I can and can't do with it. Thank You!
Your code implies that handleJSON() returns a Response object, since you then return it as the response to the original request. Your question is a little unclear, but it sounds like you are saying that this response contains a JSON body, and you want to inspect that body in your code. So you could do something like:
let jsonResponse = handleJSON();
if (jsonResponse.ok) { // check status code is 200
let jsonValue = await jsonRespnose.json();
if (jsonValue.someFlag) {
return handleHTML();
}
}
Note that calling jsonResponse.json() consumes the response body. Therefore, you can no longer return the response after this point. If you decide you want to return the JSON response to the client after all, you'll need to reconstruct it, like:
jsonResponse = new Respnose(JSON.stringify(jsonValue), jsonResponse);
This recreates the response body, while copying over the status and headers from the original response.

Make a NestJS route send in response a pretty formatted JSON

I have a NestJS route which sends back in response, a JSON not well formatted (like minified),
I want to make this JSON easier to read, like a JSON prettier or JSON formatted,
Do someone knows how to do it in NestJS ? I accept answers for other NodeJS frameworks like Express, maybe it will work in NestJS too...
Prettifying the JSON response should be the responsibility of the client, not the server. Otherwise you could be sending a lot of white space which will bloat the response size and could lead to a crash due to having a response too large. If you are using something like Postman, it should be easy to prettify it, I think Postman might do it by default. If you are looking at the response in some web browser, you could use JSON.parse() on the response and it should make the response an actual JSON which console.log() would then print in a pretty way.
You should try https://www.postman.com or https://insomnia.rest/. It can save you a lot of time when it comes to testing an API.
While you shouldn't do it in prod as mentioned above, there's number of cases where it makes a lot of sense (e.g. in dev env). You can achieve this in a bit hacky way:
Access express instance inside nest through breaking abstraction. It's not exposed on INest interface, so you'll need to cast it to any type to bypass Typescript check
Set undocumented express property "json spaces", which will set formatting for all JSON responses over the app
const app = await NestFactory.create(AppModule);
if (process.env.NODE_ENV === 'development') {
(app as any).httpAdapter.instance.set('json spaces', 2);
}
await app.listen(3000);
It works for me:
// src/main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
if (process.env.NODE_ENV !== 'production') {
app.getHttpAdapter().getInstance().set('json spaces', 2);
}
await app.listen(process.env.PORT);
}
Define return type string on your controller
Set the Content-Type: application/json response header
Use JSON.stringify to format your object with whitespace
Example controller code:
import { Controller, Get, Header } from '#nestjs/common';
#Controller('diagnostics')
export class DiagnosticsController {
#Get()
#Header('Content-Type', 'application/json')
findAll(): string {
const statusCode = 200;
const statusText = 'OK';
const info = {
self: 'NestJS Diagnostics Report',
status: {
statusCode,
statusText,
},
};
return JSON.stringify(info, null, 2);
}
}

How to use 'require' to import a JSON in NestJS controller?

I'm trying to return a json file as a controller response, but I can't get the content of the json.
import { Controller, Get, Res, HttpStatus, Query } from '#nestjs/common';
import { Response } from 'express';
import * as MOCKED_RESPONSE_TS from './data/payment-method.data'; // this ts file is imported fine
const MOCKED_RESPONSE = require('./data/payment-method-mock'); // this json file is not found
#Controller('commons')
export class CommonController {
#Get('/payment-method')
getPaymentMoethod(#Res() res: Response): any {
res.status(HttpStatus.OK).send(MOCKED_RESPONSE);
}
}
Actually the log returns: Error: Cannot find module './data/payment-method' and the app doesn't compile
I have done this with express (even with typescript) and works fine.
I don't know if i have to setup my project to read jsons (I'm newby on nest). By the moment I have created a typescript file exporting a const with the json content and I called it successfuly
I guess the problem lies in the way you import your .json file (change import instead of const)
Another advice or solution would be to leverage the .json() method of the res object (which is actually the express adapter response object).
Let's try with this code:
Your common.controller.ts file:
import { Controller, Get, Res, HttpStatus, Query } from '#nestjs/common';
import { Response } from 'express';
import * as MOCKED_RESPONSE_TS from './data/payment-method.data'; // this ts file should still be imported fine
import * as MOCKED_RESPONSE from './data/payment-method-mock.json'; // or use const inside the controller function
#Controller('commons')
export class CommonController {
#Get('/payment-method')
getPaymentMoethod(#Res() res: Response): any {
res.status(HttpStatus.OK).json(MOCKED_RESPONSE); // <= this sends response data as json
}
}
Also in your tsconfig.json file, don't forget to add this line:
tsconfig.json
{
"compilerOptions": {
// ... other options
"resolveJsonModule": true, // here is the important line, this will help VSCode to autocomplete and suggest quick-fixes
// ... other options
}
Last thoughts: you could use the sendfile() method of the res object depending on whether you want to send back a json file or the content of your json file.
Let me know if it helps ;)
first make sure you are calling it correctly.
Are you getting any response at all? if not double check your method name since its spelled like this: getPaymentMoethod and it should be this: getPaymentMethod.
Secondly I would recommend requiring outside the method and setting it to a constant.
Lastly try wrapping it in JSON.stringify() to convert the response to a json stringified object

Angular Response.json() not documented

I see Response.json() method being used a lot, and I'm using it myself, but either I'm missing something or the documentation for the Response class is incorrect.
Example:
getCurrentTime() {
return this._http.get('http://date.jsontest.com/')
.map((res:Response) => res.json())
}
On the Angular site at https://angular.io/docs/ts/latest/api/http/index/Response-class.html, I don't see the method as a member of the Response class.
If .json is not a member of the Response class, can someone point me in the direction of understanding how this works.
Or if the documentation is wrong, someone please say so.
Thanks in advance.
If you look at the API Reference for Response, you'll see that Response extends Body. If you try to search for Body, you won't find it, which probably means it isn't public. If you look at the source code for Body, you'll see the code for json
/**
* Attempts to return body as parsed `JSON` object, or raises an exception.
*/
json(): any {
if (typeof this._body === 'string') {
return JSON.parse(<string>this._body);
}
if (this._body instanceof ArrayBuffer) {
return JSON.parse(this.text());
}
return this._body;
}
Let me know if you need explanation of the source. It looks pretty self-explanitory to me though.
Actually, the HTTP Client documentation (Process the response object)
says:
Parse to JSON
This is not Angular's own design. The Angular HTTP client follows the Fetch specification for the response object returned by the Fetch function. That spec defines a json() method that parses the response body into a JavaScript object.
So Angular2 implements the Fetch Specification, which includes the specification for the mentioned Body mixin, Angular2's Response class is extending, including the .json() method.
The json() method, when invoked, must return the result of running consume body with JSON.
As you can see in peeskillet's link, Angular2 is implementing all specified methods of the Body mixin, except of formData().
I had the same problem and this is how the error go away:
In the new version of Angular 4+, you need to imports rxjs from:
import { map } from 'rxjs/operators';
instead of from importing from:
import 'rxjs/add/operator/map';
Next, change the .get() to .get() and also you have to use pipe for angular 4+ as below:
getCurrentTime() {
return this._http.get<any>('http://date.jsontest.com/')
.pipe(map((res:Response) => res.json()));
}
Hope that Helps...!

OpenERP #http.route('demo_json', type="json") URL not displaying JSON Data

I am create controller in OpenERP Framework. Following is my code and i set http.route type="http",
import openerp.http as http
from openerp.http import request
class MyController(http.Controller):
#http.route('demo_html', type="http")
def some_html(self):
return "<h1>This is a test</h1>"
Above code work perfect once i login into openerp after i modify URL http://localhost:8069/demo_html show me return result This is a test in h1 heading tag.
But same way i try to type="json" and add following json code and again try to call URL http://localhost:8069/demo_json Its not work properly and show me error "Internal Server Error".
import openerp.http as http
from openerp.http import request
class MyController(http.Controller):
#http.route('demo_html', type="http") // Work Pefrect when I call this URL
def some_html(self):
return "<h1>This is a test</h1>"
#http.route('demo_json', type="json") // Not working when I call this URL
def some_json(self):
return {"sample_dictionary": "This is a sample JSON dictionary"}
So my question is how to route json. Any help would be appreciate Thank you.
This is because there is difference between type="json" and type="http".
type="json":
it will call JSONRPC as an argument to http.route() so here , there will be only JSON data be able to pass via JSONRPC, It will only accept json data object as argument.
type="http":
As compred to JSON, http will pass http request arguments to http.route() not json data.
I think , you need to do some extra stuff while working with type="json",you have to trigger that method using json rpc from js.
like :
$(document).ready(function () {
openerp.jsonRpc("demo_json", 'call', {})
.then(function (data) {
$('body').append(data[0]);
});
return;
})
and yes do not forget to return your dictionary in list like
#http.route('demo_json', type="json")
def some_json(self):
return [{"sample_dictionary": "This is a sample JSON dictionary"}]