Automatically update Angular page on new JSON information - angularjs

I have a news app that calls information from a service. I would like to make it so that, when there is news, this is automatically added to the page.
At first, I was trying to do it by using a this.router.navigate(['/news']) in a setInterval method, but this gives the issue that if I change the page (it's a single page site), the refresh reconnects to the news page.
So, I would need something to either refresh the JSON information, or a way to stop the refresh, the moment I select another page.
The component:
import { Component, OnInit } from '#angular/core';
import { NewsService } from '../services/news.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.css']
})
export class NewsComponent implements OnInit
{
//prop
news: any;
today =
{
releaseDate: Date()
}
//constructor
constructor(private newsService: NewsService, public router: Router)
{
//getdata
this.newsService.getNews().subscribe(response => this.news = response);
}
//methode
Refresh()
{
//redirect
setInterval(() =>
{
this.today.releaseDate = Date();
//this.router.navigate(['/news']);
}, 1000);
}
//lifeCycle
ngOnInit()
{
this.Refresh()
}
}
the service:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class NewsService
{
//constructor
constructor(private http: Http)
{
}
//methode
getNews()
{
return this.http.get('https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey={apikey}').map(response => response.json());
}
and the html:
<div>
<h1 style="display:inline">Latest news</h1>
</div>
<h5 style="float:right">{{today.releaseDate|date:"HH:mm:ss"}}</h5>
<hr/>
<div *ngIf="news">
<div class="newscontainer" *ngFor="let new of news.articles, let i =index">
<div class="newsimage{{i%2}}">
<img src="{{new.urlToImage}}">
</div>
<div class="newstitle">{{new.title}}</div>
<hr />
<div class="releasedate">Release date: {{new.publishedAt|date}} at {{new.publishedAt|date:"HH:mm"}}</div>
Link to Article
<div class="synopsis">{{new.description}}</div>
</div>
</div>

Related

ANGULAR: array filter by clicking an button doesn't work

I am trying to filter my array by using modula on the id by clicking multiple buttons. I tried using pipe but it was recommended using just the .filter(). I don't know what to do, i watched many video's online but they get too complicated or i always get some error that they don't have. Or am i just going in the wrong direction for a simple onclick filter. I am quite a beginner to angular.
import { Component, OnInit} from '#angular/core';
import { StreamService } from '../stream.service';
import { Stream } from '../stream';
import { map } from 'rxjs/operators';
#Component({
selector: 'app-discover',
templateUrl: './discover.component.html',
styleUrls: ['./discover.component.scss']
})
export class DiscoverComponent implements OnInit {
streams!: Stream[];
constructor(private streamService: StreamService) {
}
ngOnInit() {
this.getStreams();
}
getStreams(){
this.streamService.getStream().subscribe((data =>{
this.streams = data;
console.log(this.streams);
}))
}
sortBack(){
this.streams.sort((a, b) => a.id - b.id);
}
filterIsUneven(){
this.streams.filter(stream => stream.id % 3)
};
}
<div class="container">
<div class="buttons">
<button (click) = "filterIsUneven()"> Games </button>
<button> Music </button>
<button> Esports </button>
<button> IRL </button>
<button>Back</button>
</div>
<div class="streams" *ngFor="let stream of streams">
<h3>{{stream.id}}</h3>
<h3>{{stream.title}}</h3>
<img src="{{stream.thumbnailUrl}}">
</div>
</div>
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Stream } from './stream';
import { Observable} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class StreamService{
constructor(private http: HttpClient) { }
getStream():Observable<Stream[]>{
return this.http.get<Stream[]>("https://jsonplaceholder.typicode.com/albums/1/photos");
}
getLiveStream(id:number):Observable<Stream[]> {
const url = `https://jsonplaceholder.typicode.com/albums/1/photos?id=${id}`;
return this.http.get<Stream[]>(url);
}
}
You are filtering, but not assigning the result, you should do this:
filterIsUneven(){
this.streams = this.streams.filter(stream => stream.id % 3)
};
The issue is that it is a permanent filter, you cannot come back to the initial list. What you can do then is making a new list:
getStreams(){
this.streamService.getStream().subscribe((data =>{
this.filteredStreams = data;
this.streams = data;
console.log(this.streams);
}))
}
filterIsUneven(){
this.filteredStreams = this.streams.filter(stream => stream.id % 3)
};
and then, use filteredStreams in the HTML instead of streams
"The filter() method creates a new array with all elements that pass the test implemented by the provided function."
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
So you have to overwrite the this.streams property:
filterIsUneven(){
this.streams = this.streams.filter(stream => stream.id % 3)
};
I guess this will work for this case, but it is not reversible.
You could introduce a new property this.filteredStreams, initialise it with the original values and project your filters and use it to display in the ngFor loop.

Call angular method in series -Highcharts

All I'm a newbie in learning Angular and highchairs. My issue is how to call angular method in series to render charts dynamically.
I referred this link ,but i'm not understanding anything from that:
link:https://www.highcharts.com/blog/tutorials/194-using-highcharts-with-angular-js/.
link: Call an angular component method when we click on highchart series
Kindly app me to solve this.
app.component.ts
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name:string = '';
age:number;
found:boolean;
constructor(private httpClient: HttpClient) { }
onNameKeyUp(event:any){
this.name = event.target.value;
this.found = false;
}
getProfile(){
this.httpClient.get(`https://my-json-server.typicode.com/techsithgit/json-faker-directory/profiles/?name=${this.name}`)
.subscribe(
(data:any[] )=>{
if(data.length){
this.age = data[0].age;
this.found = true;
}
}
)
}
}
app.component.html
<input type ="text" (keyup) = "onNameKeyUp($event)">
<button (click)= "getProfile()">Get User Details</button>
<br>
<div *ngIf="found" >
<span>{{name}}'s age is {{age}}</span>
</div>

Angular2 Typescript View not updating data after save changes and update the array (model)

I have parent component which call a REST api to get profile (JSON) data. the parent component pass this data to child component using input (array) to create dynamic form (input fields). All fields have been created successfully. the form is saving the data to DB using API post.
Problem: If the user navigate to home page and come back to profile dynamic form the data value is showing with the data version before save (old version of the data). If I refresh the screen, then I can get the correct data. the view has not been updated when load the form again. I checked the log and the JSON data being returned updated, but the form is getting the previous version of the values.
Parent Html
<df-profile [profileData]="profileData"></df-profile>
Parent Component
import { Component, ChangeDetectorRef, Input, OnInit} from '#angular/core';
import { Http } from '#angular/http';
import { Router } from '#angular/router';
import { AuthenticationService, UserService } from '../services/index';
import { ProfileModel } from '../models/index';
#Component({
moduleId: module.id,
selector: 'user-profile',
templateUrl: 'user.profile.component.html'
})
export class UserProfileComponent implements OnInit {
profileData: ProfileModel[] = [];
public isDataAvailable: boolean = false;
constructor(
public router: Router,
private userService: UserService,
private authenticationService: AuthenticationService,
) {}
ngOnInit() {
console.info("Starting GameDay Component ngOnInit ... ...");
console.info(this.authenticationService.isLoggedIn());
if (this.authenticationService.isLoggedIn()) {
this.getData().then(() => this.isDataAvailable = true);
} else {
this.authenticationService.logout();
}
}
getData(): Promise<ProfileModel<any>[]> {
return this.userService.get.profile().then(data => {
this.profileData = data[0]['profileList'];
});
}
}
Child Dynamic Form Html
<form (ngSubmit)="form.valid && onSubmit()" [formGroup]="form">
<div class="kode-team-match" *ngFor="let item of profileData">
<ul>
<li class="home-kode-field"><df-field [field]="item.field" [form]="form"></df-field></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="form-group">
<div class="col-md-12" style="text-align:center;">
<button type="submit" [disabled]="loading" class="kode-modren-btn thbg-colortwo"> Salvar</button>
</div>
</div>
</form>
<div *ngIf="payLoad" class="form-row">
<strong>Saved the following values</strong><br>{{payLoad}}
</div>
Child Dynamic Form Component
import { Component, Input, ChangeDetectorRef, OnInit } from '#angular/core';
import { FormControl, FormGroup } from '#angular/forms';
import { AuthenticationService, UserService } from '../services/index';
#Component({
moduleId: module.id,
selector: 'df-profile ',
templateUrl: 'profile.form.component.html',
providers: [ProfileControlService]
})
export class ProfileFormComponent implements OnInit {
#Input() profileData: ProfileModel[];
form: FormGroup;
payLoad = '';
constructor(
private pcs: ProfileControlService,
) {
this.profileData = [];
}
ngOnInit() {
//console.log('Starting form component ... ...');
this.form = this.pcs.toFormGroup(this.profileData);
}
onSubmit() {
this.userService.saveUserProfile(array)
.subscribe(result => {
this.isFailed = result;
if (result === true) {
this.service.success(this.translate.instant('register login'), this.translate.instant('register success'));
} else {
this.error = this.userService.errorMessage;
}
this.loading = false;
});
}
}
I'm struggling to see what I'm doing wrong here. Can anyone help?
I don't know if I need to invoke change detection and where.

Angular2 display subscription after console.log

I have different problem.
I retrieve data from Services into variable, but this data doesn't display on screen after loading (I use Subscription for this operation). All data appears on screen when I click button with function getMessages(){ console.log(this.messages);}
Can you explain why?
import {Component, NgZone, OnInit} from '#angular/core';
import {GmailApiService} from "../google/api/gmailApi.service";
import {Subscription} from "rxjs/Rx";
#Component({
selector: 'gmail-app',
templateUrl: '/app/gmail/gmail.component.html'
})
export class GmailComponent implements OnInit{
public messages: Array<string>;
subscription:Subscription;
constructor(private gmailApi: GmailApiService){
}
ngOnInit() {
this.gmailApi.checkAuthAuto('from:(xyz#zyx.com) OR to:(azx#saa.com)');
this.subscription = this.gmailApi.openMessages$
.subscribe(messages => this.messages = messages);
}
getMessages(){
console.log(this.messages);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Component files:
<template [ngIf]="messages">
Messages:
<h1 *ngFor="let message of messages">**{{message?.id}}**</h1>
</template>
<button id="button-get" (click)="getMessages(event)">
getMessages
</button>
---UPDATE---SOLUTIONS---
I found solutions for my problem, i add zone in subscription and now it's work correctly. Below I present part of my code after h
constructor(private zone:NgZone, private gmailApi: GmailApiService){
}
ngOnInit() {
this.gmailApi.checkAuthAuto('from:(xyz#zyx.com) OR to:(azx#saa.com)');
this.subscription = this.gmailApi.openMessages$
.subscribe(messages => {
this.zone.run(() => {
this.messages = messages;
});
});
}
I think it may be associated with lifecycle hooks. See this: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
I'm not sure but maybe you should implements doCheck and in subscribe call ngDoCheck method? Something like this:
export class GmailComponent implements OnInit, DoCheck {
public messages: Array<string>;
subscription:Subscription;
constructor(private gmailApi: GmailApiService){
}
ngOnInit() {
this.gmailApi.checkAuthAuto('from:(xyz#zyx.com) OR to: (azx#saa.com)');
this.subscription = this.gmailApi.openMessages$
.subscribe(messages => {
this.messages = messages;
ngDoCheck();
});
}
getMessages(){
console.log(this.messages);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngDoCheck() {
//do nothing, just call
}
}

Call 2 objects from API on button click ionic2

I got an API link where i want to get 2 objects from but it's my first time in Ionic2 so I don't know how I can create the function to call them.
I have my homepage with my button
<ion-content >
<button ion-button (click)="getObjects()"><ion-icon name="get"></ion-icon>Get</button>
</ion-content>
And in my home.ts file I've tried something like this:
import { Component } from '#angular/core';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
import { NavController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
static get parameters() {
return [[Http]];
}
constructor(public http:Http) {
}
getObjects(objectNames)
var url = 'MYurl';
var response = this.http.get(url).map(res => res.json());
return response;
}
The objects I want to call are like this:
{"lat","long","deviceID","value","id"}
Someone who can help to create the right function?
What you are getting in response variable is an Observable. You will only get the response if you subscribe to it
getObjects(objectNames) {
var url = 'MYurl';
this.http.get(url).map(res => res.json()).subscribe((response) => {
console.log(response);
}
}
You can read this if you want more details :
https://scotch.io/tutorials/angular-2-http-requests-with-observables

Resources