I have a problem on my code. I can't display my data to Vuetify Datatable, Although
it is enable Read and write on my Firebase Database:
Anyway here is my code for that, any wrong with my code? Comments were greatly appreciated:
<template v-for="user in users">
<v-data-table
v-bind:headers="headers"
:items="user"
hide-actions
class="elevation-1"
>
<template slot="items" scope="props">
<td>{{ users.title }}</td>
<td class="text-xs-right">{{users.description }}</td>
</template>
</v-data-table>
</template>
import * as firebase from 'firebase'
let config = {
//config here.....
}
let app = firebase.initializeApp(config);
let db = app.database();
let userRef = db.ref('users');
export default{
firebase:{
users:userRef
}
}
You need the data () function to return the object that is holding your data.
export default {
data () {
return {
// data for component here
}
}
}
By iterating over the template you would be creating multiple data tables. The data table component itself handles iterating over the items.
The array of objects you pass in to the :items will be available through the scope="props", the string assigned to scope can be named something besides props if you prefer. Your data will be in the props.item object. Also make sure your header array is defined somewhere.
<template>
<v-data-table
v-bind:headers="headers"
:items="exampleData" // pass the array of objects you want in the table here.
hide-actions
class="elevation-1"
>
<template slot="items" scope="props">
<td>{{ props.item.user}}</td>
<td class="text-xs-right">{{props.item.title}}</td>
</template>
</v-data-table>
</template>
import * as firebase from 'firebase'
let config = {
//config here.....
}
let app = firebase.initializeApp(config);
let db = app.database();
let userRef = db.ref('users');
export default{
data () {
return {
firebase:{
users:userRef
},
exampleData: [
{'user': 'Neo', 'title': 'CEO'},
{'user': 'Trinity', 'title': 'CTO'}
],
headers: [
{text: 'User', value: 'user', align: 'left'},
{text: 'Title', value: 'title', align: 'left'}
]
}
}
}
Related
I work on a web application with ASP.NET Core 6 and Angular 13.
This application displays a list of items successfully without any issue. My issue happens when there's pagination for the items displayed.
I get an error in the console:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
at NgForOf.ngDoCheck (common.mjs:3174:31)
at callHook (core.mjs:2561:1)
at callHooks (core.mjs:2520:1)
at executeCheckHooks (core.mjs:2452:1)
at refreshView (core.mjs:9589:1)
at refreshComponent (core.mjs:10777:1)
at refreshChildComponents (core.mjs:9376:1)
at refreshView (core.mjs:9630:1)
at refreshEmbeddedViews (core.mjs:10731:1)
at refreshView (core.mjs:9604:1)
What I tried is:
(1) Create Web API action to display all items
public async Task<IActionResult> GetAll(int pageNumber = 1)
{
var allitems = _iitem.GetAllItems();
var result = _pageHelper.GetPage(allitems.AsQueryable(), pageNumber);
var itemsdata = new ItemsPageViewModel
{
items = result.Items,
Pager = result.Pager
};
return Ok(itemsdata);
}
When I call this action method, it returns json data as shown here:
{
"items": [
{
"id": 3,
"itemNameER": "قلم",
"itemNameEN": "pen",
"description": "1"
},
{
"id": 4,
"itemNameER": "قلم",
"itemNameEN": "pencil",
"description": null
},
{
"id": 5,
"itemNameER": "قلم",
"itemNameEN": "pen2",
"description": null
}
],
"pager": {
"numberOfPages": 1,
"currentPage": 1,
"totalRecords": 3
}
}
(2) In Angular 13, I created a service in service.ts:
export class ErpServiceService {
constructor( private http: HttpClient ) { }
getAll(): Observable<any> {
return this.http.get(baseUrl);
}
(3) I created a component items logic in component.ts:
ngOnInit(): void {
this.retrieveAllItems();
}
retrieveAllItems(): void {
this.erpservice.getAll()
.subscribe(
data => {
this.items = data;
console.log(data);
},
error => {
console.log(error);
});
}
(4) I created a component view component.html:
<table id="customers">
<tr>
<th>Id</th>
<th>ItemNameAR</th>
<th>ItemNameEN</th>
<th>Description</th>
</tr>
<tr *ngFor="let item of items">
<td>{{item.id}}</td>
<td>{{item.itemNameAR}}</td>
<td>{{item.itemNameEN}}</td>
<td>{{item.description}}</td>
</tr>
</table>
How to apply pagination on item rows displayed?
I think when you process the http-response from your backend, you mistakenly assign the response-object to this.items instead of the items-array that is wrapped in the response-object.
Can you try the following?:
retrieveAllItems(): void {
this.erpservice.getAll()
.subscribe(
data => {
// Here you need to assign the array inside the data-object:
this.items = data.items;
console.log(data);
},
error => {
console.log(error);
});
}
I am using antd Select and react hook form via 'Controller'. I am populating the Select options from a fetched data with structure;
{
{
"id": "232342",
"term": "hello"
}
{
"id": "232342",
"term": "hello"
}
}
the Select component properly displays the term for selection. However, i want to retrieve both the 'id'and 'term' of the selected and use it to populate another json object.
getValues(" ") retrieves the 'id' only. How do i retrieve and access both the 'id' and 'term'.
Here is a portion of code:
import React from 'react'
import { useForm, Controller } from 'react-hook-form'
import { Select } from 'antd'
const { Option } = Select
export default function PatientRegistrationForm({ options }) {
const { register, handleSubmit, getValues, control, formState: { errors } } = useForm({
defaultValues: {
customer: "",
}
})
const children = []
for (const {id, pt: {term}} of options){
children.push(<Option key={id}>{term}</Option>)
}
// Define the retrieved values from the form
const retrievedID = getValues("customer")
// Use the retreived values to populate this object
const customer = {
customerId = retrievedID
customerName = "nothing happens here"
},
return (
<div className="">
<form onSubmit={handleSubmit(onSubmit)} className="">
<section>
<Controller
control={control}
name="customer"
render={({ field }) => (
<Select {...field} defaultValue=""
bordered={true}
filterOption={true}
className="form-control"
>
{ children }
</Select>
)}
/>
</section>
</form>
</div>
);
}
Thanks in advance for your help.
You have to retrieve the option manually using something like:
const retrievedID = getValues("customer")
const retrievedOption = options.find(option => option.id === retrievedID)
const customer = {
customerId: retrievedID,
customerName: retrievedOption.term
}
thank you #sgarcia.dev for your answer. I know its been a while but i want to put it out here incase it helps someone else. It turns out it had little to do with react hook form. Ant design select component has a prop 'labelInValue' which returns an object containing both the label and value.
Mission:
This section is to illustrate fully what I'm trying to do, and the code I'm working with.
I'm trying to set the state of a SearchContainer component using an ajax call. The data that gets returned looks something like this:
[
{
"id":903,
"name":"Adrian College",
"url":"https://en.wikipedia.org/wiki/Adrian_College",
"nickname":"Bulldogs",
"city":"Adrian",
"state":"Michigan",
"conference":"Michigan Intercollegiate Athletic Association",
"athletics_url":null,
"enrollment":20000,
"selectivity":"High",
"slug":null,
"college_sports":[
{
"sport":{
"id":71,
"name":"Softball",
"gender":"Female",
"division":"Division III"
}
},
{
"sport":{
"id":68,
"name":"Volleyball",
"gender":"Female",
"division":"Division III"
}
}
]
}
]
I'm getting this information with the following ajax (within the SearchContainer component), which I then try to set the state of filteredColleges with the data returned (referenced above):
$.ajax({
url: `/api/search/colleges.json/?query=${query}`,
method: 'GET',
success: (data) => {
this.setState({ filteredColleges: data });
}
});
I'll be updating my SearchResults component like so:
<SearchResults filteredColleges={ this.state.filteredColleges }/>
Within SearchResults, I render the following:
const colleges = this.props.filteredColleges.map( function(college) {
return <College college={college} key={college.id}/>
});
And within each College component, I want to be able to reference the list of sports that belong to that college.
My Problem:
When I try to set the state of filteredColleges within my SearchContainer component...
this.setState({ filteredColleges: data });
I get the following error:
Uncaught Error: Objects are not valid as a React child (found: object with keys {sport}).
I've tried parsing the data many different ways, but no luck. I'm pretty sure this means that I can't have the sport objects within my data array? Am I interpreting this error correctly? Is there any way to get around this?
Edit #1: Sharing my College component
import React from 'react';
export default class College extends React.Component{
constructor(props) {
super(props);
}
render() {
const { name, nickname, conference, url, enrollment, selectivity, city, state } = this.props;
return (
<tr>
<td>{ this.props.college.name }</td>
<td>{ this.props.college.nickname }</td>
<td>{ this.props.college.conference }</td>
<td>{this.props.college.url}</td>
<td>{ this.props.college.enrollment }</td>
<td>{ this.props.college.selectivity }</td>
<td>{ this.props.college.city }</td>
<td>{ this.props.college.state }</td>
<td>{ this.props.college.college_sports }</td>
</tr>
)
}
}
I think the problem is that your College component is outputting objects from the college_sports array directly, something like:
const college_sports = this.state.college.college_sports
<ul>
{ college_sports.map(sport=> <li>{sport}</li>) }
</ul>
But you can't output whole objects, like the error says. Try something like:
const college_sports = this.state.college.college_sports
<ul>
{ college_sports.map(sport=> <li>{sport.name}</li>) }
</ul>
What is happening here is that you have multiple objects with the same name in an array. You could change your api to give you an array with no object names or unique object names for this section.
First timer here....be gentle. I've searched quite a bit and didn't find anything that specifically seemed to address this problem. We have adopted Angular2 for a Singe Page Application. I have a page that has a data entry block with a grid below it. The page calls a "get" service to fill the grid upon loading. Clicking the submit button in the data entry area calls an "add" service that executes a stored proc and inserts the data into a postgre sql db. All good. Except, I'm struggling to get the grid to refresh to show the row that was newly added (even tried calling the "Get" service after the "Add"). All of the examples I've seen to date only use local arrays as the data stores (pop, push to manipulate the data). As our data is being persisted in a database, these examples don't quite get me all the way there. IContent is an interface that models the data. _contentList is an array of IContent and populated by the "Get" service. Any help appreciated!
Update: per JB's suggestion, I commented out the caching code in the get service and added an explicit call to the get service following the add >service call. Still got the same behavior.
MainComponent:
import {Component} from 'angular2/core';
import {IContent} from '../../classes/interfaces';
import {ContentService} from '../../services/content.service';
...
import {OnInit} from 'angular2/core';
import {ControlGroup, FormBuilder, Validators} from 'angular2/common';
import {Observable} from 'rxjs/Observable';
#Component({
selector: 'view',
templateUrl: 'src/views/the-view.html',
providers: [ContentService],
directives: [ROUTER_DIRECTIVES, MdToolbar, MdButton, MdCard, MD_LIST_DIRECTIVES, MdInput],
})
export class ContentMgmtComponent {
public _contentList: IContent[];
myForm: ControlGroup;
contentAdded: boolean = false;
constructor(private _formBuilder: FormBuilder, private _contentService: ContentService) {
// Programmatically build out form
this.myForm = _formBuilder.group(
{
pageID: ["", Validators.compose([Validators.required])],
zoneID: ["", Validators.required],
contentText: ["", Validators.compose([Validators.required, Validators.maxLength(10)])],
startDate: ["", Validators.required],
endDate: ["", Validators.required]
});
// Get existing pages / content
this._contentService.getAllContent()
.subscribe((content: IContent[]) => {
this._contentList = content[0]["contentInfo"];
});
}
//Add the new content to the database.
onAddContentClick(pageId: string, zoneId: string, contentText: string, startDate: string, endDate: string) {
this._contentService.addContent(pageId, zoneId, contentText, startDate, endDate)
this.contentAdded = true;
// *** PROBLEM BE HERE ... tried calling the Get Service, etc. ***
}
}
Portion of the the-view.html that should refresh:
<div class="panel panel-primary">
<div class="panel-heading"><h4>Nova Custom Content Manager</h4> </div>
<div class="panel-body">
<table class="col-md-12 table-bordered table-striped table-hover table-condensed">
<thead>
<tr>
<th>Content Id</th>
<th>Page Id</th>
<th>Zone Id</th>
<th>Content</th>
<th>Active FL</th>
<th>Start Date</th>
<th>End Date</th>
</tr>
</thead>
<tbody>
<tr class="info" *ngFor="#contentItem of _contentList">
<td>{{contentItem.contentID}}</td>
<td>{{contentItem.pageID}}</td>
<td>{{contentItem.zoneID}}</td>
<td>{{contentItem.contentText}}</td>
<td>{{contentItem.activeFlag}}</td>
<td>{{contentItem.startDate}}</td>
<td>{{contentItem.endDate}}</td>
</tr>
</tbody>
</table>
</div>
Services:
import {Injectable} from 'angular2/core';
import {Http, Response, Headers, RequestOptions, URLSearchParams} from 'angular2/http';
import {Observable} from 'rxjs/Rx';
import {IContent} from '../classes/interfaces';
import {Observer} from 'rxjs/Observer';
#Injectable()
export class ContentService {
content: IContent[]; //returned by the actual service call to the consumer
constructor(private http: Http) {
}
addContent(_pageId: string, _zoneId: string, _content: string, _startDate: string, _endDate: string) {
let body = JSON.stringify({ pageID: _pageId, zoneID: _zoneId, contentText: _content, activeFlag: "true", startDate: _startDate, endDate: _endDate });
let headers = new Headers({ 'content-type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post('http://whereever.com/api/addcontent', body, options)
.subscribe(
data => console.log(data),
err => console.log(err.json().message),
() => console.log('Authentication Complete')
);
}
getAllContent(): Observable<IContent[]> {
if (!this.content) {
//return this.http.get("/src/services/content.json")
return this.http.get("http://whereever.com/api/getallcontents")
.map((res: Response) => {
this.content = res.json();
return this.content;
})
.catch(this.handleError);
}
else {
//return cached data
return this.createObservable(this.content);
}
}
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body.data || { };
}
**strong text**...
}
Your service returns cached data. It shouldn't.
Make it make an http request every time it's called, not just the first time. Otherwise, obviously, it always returns the same, stale data.
Just a shot in the dark, but you are replacing your content list from that returned by the service. Maybe try clearing your bound list and adding the content returned from the service. I'm assuming that the binding to the list will not work if you replace the entire list with a new instance.
this._contentList = content[0]["contentInfo"]; // clear this._contentList and rebuild it from content[0]["contentInfo"]
So in my PhoneJS web app, I have a dxList widget, with checkboxes on each item. I want to be able to select multiple items, and then do something with them. I'm trying to bind the 'checked' binding to an observable, but I get an 'undefined' error.
Here's the code for the dxTemplate for the list
<div data-options="dxTemplate:{name:'item'}">
<span data-bind="text: $data.information"></span>
<div data-bind="dxCheckBox: { checked: check_boxes }"></div>
</div>
The problem is that check_boxes is in the viewModel, not the item array. I need to access values in the viewModel. I've tried viewModel.check_boxes, but with no success.
Here's the js code:
AppNamespace.otherView = function (params) {
var viewModel = {
my_list: [
{
key: 'Group 1',
items: [
{ information: 'Test 1' },
{ information: 'Test 2'},
{ information: 'Test 3' }
]
}
],
check_boxes: ko.observable(false),
//...etc
Has anyone had any experience with this, and is there a solution?
Thanks!
Knockout provides special properties to access parent binding contexts. In your case both $parent and $root should work.
More on this topic in Knockout docs: Binding context.