How can I display firebase details in a separate page in Angularfire2 - firebase

I have a static firebase database which have schema looks below.
This screenshot is a small part of it. There are many cities listed with basic info in my database.
home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { CityPage} from '../city/city';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
cityPage = CityPage;
cityinfo: FirebaseListObservable<any>;
constructor(public navCtrl: NavController, af: AngularFire) {
this.cityinfo = af.database.list('/cityinfo');
}
}
I listed firebase items in a grid at home page.
home.html
<div [navPush]="cityPage" class="demo-card-square mdl-card mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-shadow--2dp" *ngFor="let item of cityinfo | async">
<figure class="mdl-card__media">
<img src="{{ item.image }}" alt="" />
</figure>
{{ item.$key }}
</div>
But my essential problem is;
I want to display city details (summary, geography, population, zipcode, image) information in a separate page ( in city page [ city.html ] ) when I clicked an image in grid at home.html
city.html
<ion-content padding class="recipe">
<p> {{ item.summary }} </p>
<p> {{ item.geography }} </p>
<p> {{ item.population }} </p>
<p> {{ item.zipcode }} </p>
<img src="{{ item.image }}">
</ion-content>
For example, if I click Charlotte city image at home page, I want to display Charlotte city's information in city.html or if I click Raleigh city's picture, I want to display information in city.html
Any help would be appreciated, if someone can help me to success it. I couldn't do that.
Thanks everyone.

You need to pass the city information as a parameter to you city page.
Modify the city figure html to call a function that'll do that, so when you click/tap that image it'll pass the current item of your foreach to the function that'll do the work, like this:
<div [navPush]="cityPage" class="demo-card-square mdl-card mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-shadow--2dp" *ngFor="let item of cityinfo | async">
<figure class="mdl-card__media" (click)="showCityInfo(item)"> //CAN USE (tap) TOO.
<img src="{{ item.image }}" alt="" />
</figure>
{{ item.$key }}
</div>
In your Home.ts create that function and, using navController, push the city page with the city info.
showCityInfo(item) {
this.navCtrl.push(CityPage, item);
}
in your citypage, grab the city info with navparams and save it in a variable
//IMPORT NAVPARAMS FROM IONIC-ANGULAR
cityInfo: any;
constructor(public navPrms: NavParams){
this.cityInfo = navPrms.data; //here you'll get the data you passed from your home.ts
}
just populate your city.html with your city info
<ion-content padding class="recipe">
<p> {{ cityInfo.summary }} </p>
<p> {{ cityInfo.geography }} </p>
<p> {{ cityInfo.population }} </p>
<p> {{ cityInfo.zipcode }} </p>
<img src="{{ cityInfo.image }}">
</ion-content>
Hope it helps :D

Related

How to create a page from the id parameter in the url

I'm trying to create a single page from the id that is passed as a parameter.
my routes structure:
When I pass the mouse over an item in my list I get the id of the firebase document so I need to create a page to show the data in the documents based on their ids.
http://localhost:3000/category/rent/541KqSMHpU17QuYLihFs
id:
541KqSMHpU17QuYLihFs
My listItem component:
<script>
export let listing
export let id
export let handleDelete
import DeleteIcon from '../../static/assets/svg/deleteIcon.svg'
</script>
<li class="categoryListing">
<a href={`/category/${listing.type}/${id}`} class="categoryListingLink">
<img src={listing.imgUrls[0]} alt={listing.name} class="categoryListingImg" />
<div class="categoryListingDetails">
<p class="categoryListingLocation">
{listing.location}
</p>
<p class="CategoryListingName">
{listing.name}
</p>
<p class="categoryListingPrice">
${listing.offer
? listing.discountedPrice.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
: listing.regularPrice.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')}
{listing.type === 'rent' ? '/ por mês' : ''}
</p>
<div class="categoryListingInfoDiv">
<img src="/assets/svg/bedIcon.svg" alt="cama" />
<p class="categoryListingInfoText">
{listing.bedrooms > 1 ? `${listing.bedrooms} camas` : `${listing.bedrooms} cama`}
</p>
<img src="/assets/svg/bathtubIcon.svg" alt="banheiro" />
<p class="categoryListingInfoText">
{listing.bathrooms > 1
? `${listing.bathrooms} banheiros`
: `${listing.bathrooms} banheiro`}
</p>
</div>
</div>
</a>
{#if handleDelete}
<DeleteIcon
class="removeIcon"
fill="rgb(231, 76, 60)"
onClick={() => {
handleDelete(listing.id, listing.name)
}}
/>
{/if}
</li>
The important thing here is it:
<a href={`/category/${listing.type}/${id}`} class="categoryListingLink">
How do I make my [listingId] slug be the id page?
my [listingId].svelte so far:
<script>
import { page } from '$app/stores'
const listingId = $page.params.listingId
import { db } from '../../../../firebase.config.js'
// get the id parameter from the url
</script>
Happy new Year!!
I had a little trouble understanding your question at first.
As it stands now, your URIs are in the shape /category/id/[listingId], so http://localhost:3000/category/rent/541KqSMHpU17QuYLihFs won't get matched. What you need are URIs in the shape of /category/[id]/[listingId]. So you need to rename your id directory to [id] in order to make it dynamic.
You will then be able to retrieve the id the same way you do listingId:
<script>
import { page } from '$app/stores'
const { id, listingId } = $page.params
import { db } from '../../../../firebase.config.js'
// do stuff
</script>
With the above URL as an example, id will hold the value 'rent' and listingId will hold the value '541KqSMHpU17QuYLihFs'.
Hope this answers your question (and happy new year to you as well!)
Edit: a better, more explicit name for the [id] parameter would be [listingCategory] and would improve the readability of your code/the understanding of your intent.

How can I set an interpolated value, as a style property in Angular?

Before creating this question, I've read all the question existing, and none of the answers has fixed my issue.
Well, I'm fetching a data from API, {{ album.image["3"]["#text"] }} - is the link to the .png file which I would like to set as background-image of the . Here is the example of my code:
<div class="album-grid">
<div *ngFor="let album of albums">
<div class="album"> <--! I want here to set a backgroundImage for each album-->
<h4>{{ album.name }},</h4>
<h5>by {{ album.artist.name }}</h5>
<p>{{ album.image["3"]["#text"] }}</p> <--! this is the link to .png file I'm getting from server -->
</div>
</div>
</div>
here is the solutions I've tried, but none of them helped me:
[style.backgroundImage]="album.image['3']['#text']"
[style]="backgroundImage: {{album.image['3']['#text']}"
[ngStyle]="{ 'backgroundImage': album.image['3']['#text'] }"
Link to my repo -> https://github.com/paslavskyi9roman/Spotilar
On a picture, you can see a grid of albums, with the album name, artist name, and link to album cover file which need to be a background image
click here
You are missing the url() part.
Try the following (as seen in your repository)
<div class="album" [ngStyle]="{ 'backgroundImage': 'url('+ album.image['3']['#text'] + ')'}">
<h4>{{ album.name }},</h4>
</div>
<h5>by {{ album.artist.name }}</h5>
</div>

How in Vue.js could I load images once the route loads without displaying them yet?

I am trying to add a transition of 2 png into an png in the background, and be able to switch between different scenarios ( like living-room, dining-room etc). Once I click the element that select which area of the house I am choosing, the images gets fetched but because it takes some time to load, the transition doesn't happen and they just appear on top of the image on the background without transition smoothly from the side. I need a way to load the all the images once the route gets rendered, or maybe if you could give me another solution for the problem I'm happy to hear it.
This is the template
<template>
<div>
<div v-for="item in painting" :key="item.id" class="showroom">
<div class="setting">
<h1>{{ item.name }}</h1>
<h3>Choose a room:</h3>
<div v-for=" (room, idx) in rooms" :key="idx" id="roomSelection">
<img id="roomSelector" :src="room.roomview" #click="showRoom(room)">
<p>{{ room.name }}</p>
<br>
</div>
<p>Choose a wall color: <span id="colorPicker" :style="{backgroundColor: color}"><input type="color" id="base" v-model="color"></span></p>
<router-link to="/painting"><i class="fas fa-arrow-left"></i></router-link>
</div>
<div class="display">
<div :style="{backgroundColor: color}" class="wall">
<img :src="item.img">
</div>
<div class="forniture">
<transition name="slideIn">
<div v-for=" room in roomToShow" :key="room" class="setForniture">
<img class="left" :id="room.space1" :src="room.forniture1">
<img class="left" :id="room.space2" :src="room.forniture2">
</div>
</transition>
</div>
</div>
</div>
</div>
</template>
This is the script
<script>
import { mapGetters } from 'vuex'
import sofa from '../assets/sofa.png'
import lamp from '../assets/lamp.png'
import table from '../assets/table.png'
import cabinet from '../assets/cabinet.png'
import chair from '../assets/chair.png'
import sidetable from '../assets/sidetable.png'
import livingroom from '../assets/livingroom.png'
import diningroom from '../assets/diningroom.png'
import lounge from '../assets/lounge.png'
export default {
data(){
return{
color: '#243E36',
rooms: [
{ name: "lounge", space1: 'lounge1', space2: 'lounge2', forniture1: chair, forniture2:sidetable, roomview: lounge},
{ name: "livingroom" , space1: 'livingroom1', space2: 'livingroom2', forniture1:sofa, forniture2:lamp, roomview: livingroom },
{ name: "diningroom" , space1: 'diningroom1', space2: 'diningroom2', forniture1: table, forniture2: cabinet, roomview: diningroom }
],
roomToShow: [],
}
},
computed: {
...mapGetters([
'showPainting',
'forSale',
'painting'
]),
},
methods: {
showRoom(room) {
setTimeout( () => {
this.roomToShow.shift();
this.roomToShow.push(room);
}, 100)
}
}
</script>
The easiest way to solve this issue is to just hide the images with CSS but nevertheless load all from the beginning (render the elements). You can do that by dynamically adding a class to the currently visible image with :class="".
A more complex solution, which gives you also a callback for when the images are loaded, is to create a new Image() for all images and react to onload/onerror. Like this, you can load all the images in the beginning with JS abd without changing the HTML. Here is an example for this use case: How to create a JavaScript callback for knowing when an image is loaded?

Can't extend data from Pin model

My models.py looks like this.
model.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Pin(models.Model):
proffession = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.proffession
def get_absolute_url(self):
return reverse('pin-detail', kwargs={'pk': self.pk})
Views.py
def home(request):
context = {
'pins': Pin.objects.all(),
}
def get(self, request):
users = User.objects.exclude(id=request.user.id)
return render(request, 'vlog/home.html')
return render(request, 'vlog/home.html', context)
class PinListView(ListView):
model = Pin
template_name = 'vlog/home.html' # <app>/<model>_<view_type>.html
context_object_name = 'pins'
ordering = ['-date_posted']
paginate_by = 5
While extending data from Pin model. It doesn't provide any result.
base.html
<div class="col-md-4">
<div class="content-section">
<h3>Available People</h3>
{% for pin in pins %}
<article class="media content-section">
<!-- <img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}"> -->
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'profileu' %}">{{ pin.username }}</a>
</div>
<p class="article-metadata">{{ pin.content }}</p>
</div>
</article>
{% endfor %}
</div>
</div>
How can I extend data from Pin Model in ListView. Please Share your suggestion

Linking Title to an URL in drupal

I am just new to Drupal and trying to update some existing applications. I am trying to associate the title to an URL. I tried this
link(title, content.field_url)
But I don't think I am right track. Any help would be appreciated. Following is the twig templet for displaying persons.
<div class="wdn-col" style="margin-top:2.4em;">
<div class="wdn-grid-set">
<div class="wdn-col-three-sevenths">
<div class="wdn-frame">{{ (content.field_portrait) }}</div>
</div>
<div class="wdn-col-four-sevenths">
<h5 class="wdn-brand clear-top">{{title }}
<span class="wdn-subhead">{{ (content.field_position) }}, {{ (content.field_institution) }}</span></h5>
<p style="font-size:smaller;">{{ (content.field_unit) }}</p>
<p>{{ (content.field_email_address) }}</p>
</div>
</div>
</div>
Try like this way....
{{ title }}

Resources