Angular 5 httpClient get Request vscode json error - json

My code is working perfectly, I just have a problem where my data from the get request is underlined in red and I don't understand how to fix this. The alert works perfectly. It alerts the SessionID that I need. I would just like to know how I can remove this underlined error, or maybe I am not doing the get request correctly? Thank you for any help :)

try below code :
this.httpClient.get('hidden').subscribe((myData:any)=>{
alert(myData.utLogon_responce.sessionId)
})
add : any
thanks,

The red wiggly lines that show up are indicating the type error. This indicates that it cannot determine the utLogon_response in type definition of myData variable. This can be solved by either of following ways:
Make myData as type any (simple, quick and easier)
this.httpClient.get('hidden')
.subscribe((myData: any) => {
alert(myData.utLogon_response.sessionId);
})
However, my understanding is that one should use any only in extreme conditioms since this is more like defeating the very purpose of Typescript.
Define proper type for myData and use it (simple, slight coding but most appropriate)
interface IHiddenData {
utLogon_response: any {
sessionId: string;
}
}
this.httpClient.get('hidden')
.subscribe((myData: IHiddenData) => {
alert(myData.utLogon_response.sessionId);
})
I hope this helps!
NOTE: Somehow, this code is not getting properly formatted by the editor and I do know how to set it right.

Related

Swiftsoup parsing is not finding all HTML classes

I have a method to parse website with using Swiftsoup go get the price of a product:
#objc func actionButtonTapped(){
let url = "https://www.overkillshop.com/de/c2h4-interstellar-liaison-panelled-zip-up-windbreaker-r001-b012-vanward-black-grey.html"
let url2 = "https://www.asos.com/de/asos-design/asos-design-schwarzer-backpack-mit-ringdetail-und-kroko-muster/prd/14253083?clr=schwarz&colourWayId=16603012&SearchQuery=&cid=4877"
do {
let html: String = getHTMLfromURL(url: url2)
let doc: Document = try SwiftSoup.parse(html)
let priceClasses: Elements = try doc.select("[class~=(?i)price]")
for priceClass: Element in priceClasses.array() {
let priceText : String = try priceClass.text()
print(try priceClass.className())
print("pricetext: \(priceText)")
}
} catch Exception.Error(let type, let message) {
print(message)
} catch {
print("error")
}
}
The method works fine for url but for url2 it is not printing all all the classNames even though they match the regex. This is where the price actually is:
<span data-id="current-price" data-bind="text: priceText(), css: {'product-price-discounted' : isDiscountedPrice }, markAndMeasure: 'pdp:price_displayed'" class="current-price">36,99 €</span>
The output of the function is this:
product-price pricetext:
stock-price-retry-oos
pricetext:
stock-price-retry
pricetext:
It is not printing class=current-price. Is something wrong with my regex or why does it not find that class??
EDIT:
I found out that the price is not actually inside the HTML of url2. Only the classes that are actually printed out are inside. What's the reason for that and how can I solve that?
The html is not static. It can change over time. If you make a get request to the site's URL you will get the initial value of the html for that site.
But on browsers there is this thing, called javascript, that can make the page's HTML change over time. It's quite common actually:
- The site gets loaded at first with some javascript
- The javascript (developed by the site's creator) than runs and does stuff
- Content dynamically changes by calling some API by that javascript
You can't scrape that content by HTML scraping of the base URL.
If you ask me how I'd do that anyway, is by looking for the site's HTTP requests where it gets the content. Look at that API and use that API myself. Get the data, and store it in some of my servers.
Than on the client I call my server's API to get that data.
Also I'm not really sure that's legal.
But, as far as I understood by your last couple questions, you don't want to do that.
If you really need to do that on the client, you can use WKWebView, load the page, wait for the content to show up, and then get the current HTML of the page by doing something like this:
webView.evaluateJavaScript("document.documentElement.outerHTML.toString()",
completionHandler: { (html: Any?, error: Error?) in
print(html)
})
Look at this answer for more about this.
I hope this solves all of your problem, because I think I don't have much more time to help you :D

Angular: Routing between pages using condition

I am trying to route between pages using basic if condition in Angular.
GoToHome() {
if(this.router.url=='/chat'){
console.log(this.router.url)
this.router.navigate(['login']);
} else {
this.router.navigate(['people']);
}
}
The problem is that the route chat isn't really correct, there are many pages in chat (chat\x , chat\y and many others) I want that it will work for all the pages in chat, but right now it doesn't work. If I write a specific route like chat\x it does work, but only for x. Is there a way to do it for all?
you can read and check Guards. Read about CanActivate method, maybe it will help you?
RouteGuards might do a better job of handling the redirects as per your requirement.
But a quick workaround would be to do a split() on the URL and compare for the chat part. Try the following
if(((this.router.url).split('/')[1]) === 'chat') {
// proceed
}
As other had said, best solution is to use Angular Guard https://medium.com/#ryanchenkie_40935/angular-authentication-using-route-guards-bf7a4ca13ae3.
Anyway to resolve your problem you can use startsWith() function which determines whether a string begins with the characters of a specified string.
GoToHome() {
if((this.router.url).startsWith('/chat'){
console.log(this.router.url)
this.router.navigate(['login']);
} else {
this.router.navigate(['people']);
}
}

Display JSON object nicely with Syntax Hihjlighter

I'm trying to display a JSON object nicely (this means on several lines with indentation) with Alex Gorbatchev plugin : http://alexgorbatchev.com/SyntaxHighlighter/
Unfortunately, it all displays on a single line.
I'm using the javascript brush.
I've created a code pen : http://codepen.io/hugsbrugs/pen/XJVjjP?editors=101
var json_object = {"hello":{"my_friend":"gérard", "my_dog":"billy"}};
$('#nice-json').html('<pre class="brush: javascript">' + JSON.stringify(json_object) + '</pre>');
SyntaxHighlighter.highlight();
Please don't give a list of other plugins since I know there is a bunch but I don't want to load additional plugins ... I'd like to achieve it with this plugin.
Thanks for your help
Try indenting the json with the stringify method.
JSON.stringify(json_object, undefined, 2);
You can use the optional third parameter of JSON.stringify(...) which is the space argument.
Change:
JSON.stringify(json_object)
to:
JSON.stringify(json_object, null, '\t')
Here is your codepen updated to show the result of the above modifications. The above modification causes your JSON to be pretty printed over multiple lines.

Binding dynamically within an ng-repeat expression

For a TV Guide, I am trying to create a dynamic expression within an ng-repeat directive as follows:
<div ng-repeat="programme in programmes['{{channel}}-wed-jan-14']" alt="{{channel}}">
{{channel}} in my controller should evaluate to something like "eTV". The binding is working fine with the alt="{{channel}}" instance but not with the array instance. Angular simply serves up the line of code commented out. If I hardcode the "eTV" string in place of the {{channel}}, it works fine.
Am I trying to ask Angular to do what it is not designed for, or is it possibly my array handling which is dodgy?
Okay, not sure if I just asked a dumb question, but in the absence of responses, I managed to figure out a solution by writing a filter as follows:
Template:
<div ng-repeat="programme in programmes | getChannelDay:channel:dayString" alt="{{channel}}">
Controller filter:
app.filter('getChannelDay', function() {
return function(programmes, channel, dayString) {
return programmes[channel + dayString];
};
});
The issue with my initial problem
<div ng-repeat="programme in programmes['{{channel}}-wed-jan-14']" alt="{{channel}}">
is that I was trying to put {{channel}} inside the expression, but that is the format for markup.
I tried to use the following instead:
<div ng-repeat="programme in programmes['channel + daystring']" alt="{{channel}}">
but I am doing something wrong here. I am pretty sure there is a way to get this to work - if anyone knows, please comment.

AngularJS: Writing to and Reading from textarea with multilines

I can't believe why I can't find anything to this topic ...
I got a form with let's say lastname (input), firstname (input), description (textarea as I want provide several lines). Let's start with the creation of a new object:
Okay, you type something in like
lastname: fox
firstname: peter
description:
what can I say ..
well I'm THE guy
bye
This arrives at my Java Spring MVC Backend Controller as what can I say ..\nwell I'm THE guy\n\nbye which is fine as I can determine where line breaks are.
So, now I want to edit this object. Thus I want to read the stored data and put it in the form. On Serverside I now edited the description text so that I replaced the \n with <br> so that I have HTML breaks.
Now I use angular-sanitize (ngSanitize dependency) and use the directive ng-bind-html="my.nice.description"
If I use this on a DIV, everything works fine, HTML gets rendered and I get my breaks. So this works perfectly:
<span ng-bind-html="my.nice.description"></span>
or one of the following:
<div ng-bind-html="my.nice.description"></div>
<p ng-bind-html="my.nice.description"></p>
BUT as I want to (re)fill my form so the user can edit his previous input, I still use a textarea. Like this:
<textarea ng-bind-html="my.nice.description"></textarea>
And this does NOT work in any way. Which means that I get 's in my text, unrendered.
Though this seems like a ridicilous normal task. It's a form with a simple multiline box, so I want to write my several lines and I want to read them and I want to edit them.
As I am rather a backend guy and not very familiar with HTML and AngularJS I hope that I'm just using the wrong html element or something like this ... Maybe someone can help me out? It's frustrating :(
Thanks in advance and I guess and hope this is not a real hard task :x
store 'br' in your model, so you can use ng-bind-html. add a directive to your textarea which makes the conversion between your $viewVale ('\n') and your model.
.directive('lbBr', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
return;
}
ngModel.$parsers.unshift(function(value) {
return value.replace(new RegExp('\n', 'g'), '<br />');
});
ngModel.$formatters.unshift(function(value) {
if (value) {
return value.replace(new RegExp('<br />', 'g'), '\n');
}
return undefined;
});
}
};
});
<textarea> elements cannot contain other elements (in your case, <br>'s). They are standalone. You'll have to convert the variable-returned-from-server-containing-<br>'s back to \n's, and vice versa back and forth. You can use an angular directive that handles that for you.