I am building a simple chat system for users within my DB, and I want the user to be able to reply to messages, but to show in chronological order. I cannot get the nested foreach loop to show any results. Here is what i have so far.
Friends Database with both users from my users table, id's 2 and 15.
| id | user_id | friend_id | accepted |
| 1 | 15 | 2 | 1 |
Status Database
| id | user_id | parent_id | body |
| 28 | 15 | NULL | Hello |
| 29 | 2 | 28 | Hi, how are you |
This is my Members Controller with the query builder.
public function members(Request $request, Response $response, $args) {
$token = User::where('id', $this->auth->user()->id)->first();
$order = Order::where('user_id', $this->auth->user()->id)->first();
if(!$order) {
$token = $args['token'];
return $response->withRedirect($this->router->pathFor('membersPaymentPlan', compact('token')));
}
$statuses = Status::notReply()->where(function($query) {
return $query->where('user_id', $this->auth->user()->id)->orWhereIn('user_id', $this->auth->user()->friends()->pluck('id'));
})->orderBy('id', 'DESC')->get();
return $this->view->render($response, 'members/index.php', compact('token', 'statuses'));
}
In my User Model, I have method relationships.
public function statuses() {
return $this->hasMany('Base\Models\Messaging\Status', 'user_id');
}
public function friendsOfMine() {
return $this->belongsToMany('Base\Models\User\User', 'friends', 'user_id', 'friend_id');
}
public function friendOf() {
return $this->belongsToMany('Base\Models\User\User', 'friends', 'friend_id', 'user_id');
}
public function friends() {
return $this->friendsOfMine()->wherePivot('accepted', true)->get()->merge($this->friendOf()->wherePivot('accepted', true)->get());
}
In my Status Model. I have method relationships.
public function user() {
return $this->belongsTo('Base\Models\User\User', 'user_id');
}
public function scopeNotReply($query) {
return $query->whereNull('parent_id');
}
public function replies() {
return $this->hasMany('Base\Models\Messaging\Status', 'parent_id');
}
Here is where the problem is. This is my nested foreach loop within my Twig template.
{% for status in statuses %} // This loop works ok showing all results
{% for reply in status.replies() %} // HERE IS THE PROBLEM - No results
<div class="from-them margin-bottom-10">
<p class="nomargin">{{ reply.body | nl2br }}</p>
</div>
<div class="clearfix"></div>
{% endfor %}
<div class="from-me margin-bottom-10">
<p class="nomargin">{{ status.body | nl2br }}</p>
</div>
<div class="clearfix"></div>
{% endfor %}
Why won't the nested foreach loop show any results from the status.replies() relationship? What do I have wrong here?
Related
I have two classes:
Row (Child Class)
mySpreadsheet (Parent Class)
I am trying to do something like this:
Row:
class Row extends React.Component {
constructor(props, ref) {
super(props);
this.state = { selectedFile: null}
this.handleUpload = this.handleUpload.bind(this);
}
//This handleUpload is being called by the parent class of this Row class through ref.
handleUpload(ev) {
ev.preventDefault();
const data = new FormData();
data.append('file', this.uploadInput.files[0]);
data.append('filename', this.fileName.value);
data.append('comment',this.comment.value);
data.append('id', this.fileName.id);
fetch('http://localhost:8000/upload', {
method: 'POST',
body: data,
}).then((response) => {
response.json().then((body) => {
this.setState({ selectedFile: `http://localhost:8000/${body.file}` });
});
});
}
rowCreator() {
let row = []
for (var i = 0; i < 10; i++) {
row.push(
<td>
<div>
<input type="file" name={`file${this.props.id*10 + i}`} id={this.props.id*10 + 1} ref={(ref) => { this.uploadInput = ref; }}/>
<input type="text" name={`fileName ${this.props.id*10 + i}`} ref={(ref) => { this.fileName = ref; }} placeholder="Name the file with extension"/>
<input type="text" ref={(ref) => { this.comment = ref; }} placeholder="Comment"/>
</div>
</td>
)
}
return row
}
render() {
return (
<tr>
<td class="align-middle ">
<div class="cell">
<input type="text" placeholder={this.props.id + 1} />
</div>
</td>
{this.rowCreator()}
</tr>
)
}
}
and in mySpreadsheet I am creating each row in a table using Row class as follows:
<tbody id="tbody">
{this.state.data.map(id => (
<Row id={id} ref={this.rowRef} />
))}
</tbody>
I am using the handleUpload() function from the Row (child) by using rowRef:
this.rowRef = React.createRef();
upload(ev) {
this.rowRef.current.handleUpload(ev);
}
<button onClick={this.upload}>
Upload Files
</button>
But I am getting error (500) while doing a POST request through my website. Is it because of the ref I am using in Row such as uploadInput, for appending data in handleUpload? Is there any way to make a unique ref for all the cells in my table? Or can I use something else like id or name which I have made uniquely for all different cells using this.props.id*10 + i for each iteration, i while making columns for one row?
You can create refs for mapped elements and put it in an array based on their indexes or ids.
// constructor state part
constructor() {
this.refs = [];
}
// render part
{this.state.data.map(id => (
return <Row id={id} ref={itemRef => this.refs[id] = itemRef} />
))}
And in my opinion, you should hold the values instead of the components itself in an array.
Id must be unique and if the map parameter is an object, you should use a unique property instead of the key which comes with map. If you use keys, React will not keep track of your component while you' re updating your state.
(Using PostgreSQL)
So, I have these (User and Vote) Objection.js models:
const { Model } = require('objection');
class User extends Model {
static get tableName() {
return 'users';
}
static get relationMappings() {
return {
posts: {
relation: Model.HasManyRelation,
modelClass: require('./Post'),
join: {
from: 'users.id',
to: 'posts.userId',
},
},
comments: {
relation: Model.HasManyRelation,
modelClass: require('./Comment'),
join: {
from: 'users.id',
to: 'comments.userId'
}
},
votes: {
relation: Model.HasManyRelation,
modelClass: require('./Vote'),
join: {
from: 'users.id',
to: 'votes.userId'
}
}
};
}
}
module.exports = User;
const { Model } = require('objection');
class Vote extends Model {
static get tableName () { return 'votes' }
static get relationalMappings () {
return {
user: {
relation: Model.BelongsToOneRelation,
modelClass: require('./User'),
join: {
from: 'votes.userId',
to: 'users.id'
}
},
post: {
relation: Model.BelongsToOneRelation,
modelClass: require('./Post'),
join: {
from: 'votes.postId',
to: 'posts.id'
}
}
}
}
}
module.exports = Vote;
The psql command \d users returns:
Table "public.users"
Column | Type | Collation | Nullable | Default
-------------+------------------------+-----------+----------+-------------------
id | uuid | | not null | gen_random_uuid()
username | character varying(128) | | not null |
displayname | character varying(128) | | not null |
email | character varying(256) | | not null |
description | character varying(256) | | |
password | character varying(512) | | not null |
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_id_index" btree (id)
Referenced by:
TABLE "comments" CONSTRAINT "comments_userid_foreign" FOREIGN KEY ("userId") REFERENCES users(id)
TABLE "posts" CONSTRAINT "posts_userid_foreign" FOREIGN KEY ("userId") REFERENCES users(id)
TABLE "votes" CONSTRAINT "votes_userid_foreign" FOREIGN KEY ("userId") REFERENCES users(id)
And the psql command \d votes returns:
Table "public.votes"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+-------------------
id | uuid | | not null | gen_random_uuid()
userId | uuid | | not null |
postId | uuid | | not null |
up | boolean | | not null |
down | boolean | | not null |
Indexes:
"votes_pkey" PRIMARY KEY, btree (id)
"votes_id_index" btree (id)
Foreign-key constraints:
"votes_postid_foreign" FOREIGN KEY ("postId") REFERENCES posts(id)
"votes_userid_foreign" FOREIGN KEY ("userId") REFERENCES users(id)
What i would like to do is use some sort of Model class method (on the class User) to set the properties upvotes (number of Votes with up set to true), downvotes (number of Votes with down set to true) and balance (upvotes - downvotes).
I was goin through some tutorial, and i got into an issue with The error 'cannot read property 'map' of undefined'.Please help me with the following code.
TypeError: Cannot read property 'map' of undefined
TodoItems.render
C:/Users/hp/Desktop/todo_list/src/TodoItems.js:10
7 |
8 | render(){
9 | var todoEntries = this.props.entries;
> 10 | var listItems = todoEntries.map(this.createTasks);
| ^ 11 |
12 | return (
13 | <ul className="theList">
View compiled
▶ 23 stack frames were collapsed.
import React, { Component } from "react";
class TodoItems extends Component{
createTasks(item) {
return <li key={item.key}>{item.text}</li>
}
render(){
var todoEntries = this.props.entries;
var listItems = todoEntries.map(this.createTasks);
return (
<ul className="theList">
{listItems}
</ul>
);
}
}
export default TodoItems;
and the TodoList file code is:
render() {
return (
<div className="todoListMain">
<div className="header">
<form onSubmit={this.addItem}>
<input ref={(a) => this._inputElement = a}
placeholder="enter task">
</input>
<button type="submit">add</button>
</form>
</div>
<TodoItems entries={this.state.items}/>
</div>
);
}
}
export default TodoList;
You're trying to pass this.state.items as entries, but it seems that it's not an array but undefined.
You could just make it an array by default by doing something like the following -
class MyComponent extends Component {
state = {
items: []
}
}
I currently have a step to verify a payment
Then I have these payments:
| Payment Type | Amount |
| Cash | 1.20 |
I would like to replace the 'Amount' with a variable, such as bill total which would be in the TestContext.
Then I have these payments:
| Payment Type | Amount |
| Cash | <billTotal> |
I've attempted to pre-process the table before creating my set, but I cannot assign to the TableRow value. Is there a standard way to achieve this? Is there a different approach I should be taking?
I ended up using something like this before creating my set:
public void AdjustTable(Table table)
{
foreach (var row in table.Rows)
{
foreach (var key in row.Keys)
{
if (row[key] == "<userFirstName>")
{
row[key] = this.testContext.CustomerProfile.Customer.Name.First;
}
else if (row[key] == "<userLastName>")
{
row[key] = this.testContext.CustomerProfile.Customer.Name.Last;
}
}
}
}
Still open to suggestions!!
I am pretty new to Twig. I have a class called Session and a static function called get I want to return the content of Session::get('user_name'). Is it even possible without modifying anything?
I tried {{ constant('Namespace\\Session::get("user_name")') }} and {{ Session.get('user_name') }} but it doesn't seem to work.
You could use Twig Extension like below:
class CustomExtension extends \Twig_Extension {
public function getFunctions() {
return array(
new \Twig_SimpleFunction('static_call', array($this, 'staticCall')),
);
}
function staticCall($class, $function, $args = array()) {
if (class_exists($class) && method_exists($class, $function)) {
return call_user_func_array(array($class, $function), $args);
}
return null;
}
}
Usage in in twig:
{{ static_call('AppBundle\\Entity\\YourEntity', 'GetSomething', ['var1', 'var2']) }}
I found the answer. I simply added the following code right after new Twig_Enviroment($twig_loader)
$twig = new Twig_Environment($twig_loader);
$twig->addFunction('_call', new Twig_Function_Function(
function($class, $function, $arguments = array())
{
return call_user_func(array($class, $function), $arguments);
})
);
In Twig
{{ _call('Session', 'get', 'user_name')|raw }}