Trying to import excel data to my mysql db and getting ErrorException Undefined offset: 0.
Tried using var_dump($row) to check the array of the row of the data. It looks off and not sure how to make the data shows nicely so that able to pass to db.
array(5) { ["a"]=> string(1) "B" ["white"]=> string(5) "Green" ["example1_at_gmailcom"]=> string(18) "example2#gmail.com" [60123456789]=> int(60162313142) [5]=> int(5) }
This is my excel data:
Model
public function model(array $row)
{
var_dump($row);
return new ContactList([
'first_name' => $row[0],
'last_name' => $row[1],
'email' => $row[2],
'phone' => $row[3],
'group_id' => $row[4],
]);
}
I already tried using replacing the $row[] with string and it works perfectly storing the data into my db.
Controller
if($request->hasFile('selected_file')){
$file = $request->file('selected_file');
Excel::import(new ContactListsImport, $file);
return redirect()->back()->with('success', 'Data saved successfully!');
}
You need to remove the WithHeadingRow interface from your Import class to use numeric indexes for the array.
As per the documentation, when your Import class implements WithHeadingRow it will use the first row for the indexes of the array and in turn remove it from the rows that are provided.
Related
Recently, I changed key of object in MongoDB.
{
links: {
changed: 'value',
notchanged: 'value'
}
}
This is what I get from my MongoDB collection. Data which key is not changed is still readable by links.notchanged but data which key is changed like links.changed is not readable and only outputs undefined. Node.js gets and reads the whole links data correctly but when it comes to links.changed it doesn't. How do I solve this problem? Code below:
scheme.findOne({}, (err, data) => {
if (err) res.send('ERR')
else {
console.log(data) // prints full data, same as JSON above
console.log(data.links.changed) // undefined
}
}
You are matching {class:'210'}.. Is it available in document. Probably Your query returns empty object in data . Confirm the match query... Otherwise your code seems ok.
await db1.findOne({class: "210"}, (err, data) => {
console.log(data.links.changed) // returns value
})
Or Try the code like this
await db1.find({ class: "210" }).toArray()
.then(data => {
console.log(data[0].links.changed) //"value"
});
You should make a variable instead of an object for this. For example: Use changed and assign it value as true or false
I have this class:
class BookUnitQuestionSchema extends Schema {
up () {
this.create('book_unit_question', (table) => {
table.increments()
table.integer('book_unit_id').references('id').inTable('book_unit')
table.string('correct_answer_description')
table.boolean('status').defaultTo(false)
table.integer('user_id').references('id').inTable('users')
table.timestamps()
})
}
down () {
this.drop('book_unit_question')
}
}
I need to change the data type of the column correct_answer_description to text.
If i change my actually up() method to:
table.text('correct_answer_description')
and make a: adonis migration:refresh
All table is recreated and i lose the data in this table.
How i can only change the datatype without lose the data?
I try something like:
this.alter('book_unit_question', (table) => {
table.text('correct_answer_description')
})
And make a:
adonis migration:run
But i get:
Nothing to migrate
You need to create a new migration file like :
Type modification (new migration file) : .alter()
class BookUnitQuestionSchema extends Schema {
up() {
this.alter('book_unit_questions', (table) => {
table.text('correct_answer_description').notNullable().alter();
})
}
// reverse modification
down() {
this.table('book_unit_questions', (table) => {
table.string('correct_answer_description').notNullable().alter();
})
}
}
and run pending migrations :
> adonis migration:run
I'm trying to update a column in users table the column type is json.
column name is test.
and the column consists of an object default value for example is
{a: "text", b: 0}
how to update let's say the object key b without changing the whole column
the code i'm using is
knexDb('users').where({
email: email
})
.update({
test: { b: 1 }
})
second solution
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1])
})
first solution changes the whole column cell and test will be only { b: 1 }
second solution doesn't work it give an error
function jsonb_set(json, unknown, unknown) does not exist
The expected result
is to manage to update only a certain key value in an object without changing the whole object.
PS
I also want to update an array that consists of objects like the above one for example.
[{a: "text", b: 0}, {c: "another-text", d: 0}]
if i use the code above in kenxjs it'll update the whole array to only {b: 1}
PS after searching a lot found that in order to make it work i need to set column type to jsonb, in order the above jsonb_set() to work
but now i'm facing another issue
how to update multiple keys using jsonb_set
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1]),
test: knexDb.raw(`jsonb_set(??, '{a}', ?)`, ['test', "another-text"]),
})
the first query key b is now not updating, in fact all updates don't work except the last query key a, so can some explain why ?
Your issue is that you're overwriting test. What you're passing into update is a JS object (docs). You cannot have multiple keys with identical values (docs). You'll have to do something like this where you make 1 long string with all your raw SQL as the value to test.
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`
jsonb_set(??, '{a}', ?)
jsonb_set(??, '{b}', ?)
`,
['test', "another-text", 'test', 1])
})
Probably a better option exists - one that would be much more readable if you have to do this for several columns is something like what I have included below. In this example, the column containing the jsonb is called json.
const updateUser = async (email, a, b) => {
const user = await knexDb('users')
.where({ email })
.first();
user.json.a = a;
user.json.b = b;
const updatedUser = await knexDb('users')
.where({ email })
.update(user)
.returning('*');
return updatedUser;
}
Update/insert a single field in a JSON column:
knex('table')
.update( {
your_json_col: knex.jsonSet('your_json_col','$.field', 'new value')
})
.where(...)
Update/insert multiple fields
Option 1 (nested)
knex('table')
.update( {
your_json_col: knex.jsonSet(knex.jsonSet('your_json_col','$.field1', 'val1')
'$.field2', 'val2')
})
.where(...)
Option 2 (chained)
knex('table')
.update( {
your_json_col: knex.jsonSet('your_json_col','$.field1', 'val1')
})
.update( {
your_json_col: knex.jsonSet('your_json_col','$.field2', 'val2')
})
.where(...)
Sorry for long text but my problem is long :-) I made grid like this
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'name'=>'title',
'type'=>'raw',
'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
),
array(
'name'=>'create_time',
'type'=>'raw',
'value' => 'Yii::app()->dateFormatter->format("yyyy", $data->create_time)',
),
),
));
and then i want to filtering by date like title filtering, by textfield.
I made controller with code
$model=new Post('search');
if(isset($_GET['Post']))
$model->attributes=$_GET['Post'];
$this->render('admin',array(
'model'=>$model,
));
and search methode in model
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('title',$this->title,$partialMatch=true);
$criteria->compare('create_time',$this->create_time,$partialMatch=true);
return new CActiveDataProvider('Post', array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'status, update_time DESC',
),
));
}
i don't forget abount rules()
array('title, create_time', 'safe', 'on'=>'search')
I have got two records wiht today's date. Title filtering works fine but when i type '2015' in 'create_time' column filter textfield and press enter i get "no results found".
I tried this:
array(
'name'=>'create_time',
'type'=>'raw',
'value' => 'Yii::app()->dateFormatter->format("dd MMMM yyyy", $data->create_time)',
'filter' => CHtml::listData(Post::model()->findAll(array('order'=>'create_time')), 'create_time', 'create_time'),
),
and it's seems to work but in my database, create_time is integer(11) (required) and listdata values is number not date and represents full date, not only year.
I controller i made array with unique year values from create_time record's values. Outputs array like $rok['2015'] => '2015'
$model_post = new Post;
$wyniki = $model_post::model() -> findAllBySql('SELECT create_time FROM tbl_post');
for($i=0;$i<count($wyniki);$i++)
{
$rok_temp[$i] = Yii::app()->dateFormatter->format("yyyy", $wyniki[$i]->create_time);
$rok[$rok_temp[$i]] = $rok_temp[$i];
}
$rok = array_unique($rok);
I send $rok to view and
array(
'name'=>'create_time',
'type'=>'raw',
'value' => 'Yii::app()->dateFormatter->format("dd MMMM yyyy", $data->create_time)',
'filter' => $rok,
),
and
$criteria->compare('create_time',Yii::app()->dateFormatter->format("yyyy", $this->create_time));
but then i get "no results found" when filtering.
What i made wrong?
Your time is stored as a UNIX timestamp. You therefore have to do some conversion on the input from the filter to change it to UNIX also. First, create a variable to hold the year in your model
class MyModel extends ... {
public $create_year;
}
Then add this variable to your rules:
array('create_year', 'safe', 'on' => 'search')
array('create_year', 'numerical', 'integerOnly' => true)
Next add the conversion rules for the year to your search() i.e
public function search() {
...
if ($this->create_year) {
$criteria->addBetweenCondition('create_time',
strtotime($this->create_year.'-01-01 00:00:00'),
strtotime($this->create_year.'-12-31 23:59:59')
);
}
...
}
Lastly change your filter to a dropdown to reduce invalid entries:
'filter' => CHtml::activeDropDownList(
$model,
'create_year',
array_combine(range(1900, 2099), range(1900, 2099),
array('prompt' => 'Any year')
)
There is a serch form on the mainpage of a realestate agency. The data about objects is stored in the table "realty" that uses relations. For example, there are related tables category (residential, commercial, land plots), deal (buy, sell, rent), object_type (apartment, house, office).
Then different categories have different properties and and there are three bootstrap tabs in the search form: residential, commercial, land plots. Under each tab there are selects and input fields that are specific for the choosen tab.
In the most cases, the examples of using Search model are given within a gridview.
Is it possible to adapt Search model logic so that it could return the array of results from the table 'realty' based on the values indicated in the search form on the mainpage ?
Yes, of course you can. you have several options:
Solution 1 - worst solution but the answer to your question
modify the search function of the model (or create a new function). The search functions usually looks like this
public function search($params)
{
$query = Bookmark::find()->where('status <> "deleted"');
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => Yii::$app->session->get(get_parent_class($this) . 'Pagination'),
],
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere([
'status' => $this->status,
'id' => $this->id,
'reminder' => $this->reminder,
'order' => $this->order,
'update_time' => $this->update_time,
'update_by' => $this->update_by,
'create_time' => $this->create_time,
'create_by' => Yii::$app->user->id,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'url', $this->url]);
return $dataProvider;
}
You can change it to something like
public function search($params)
{
$query = Bookmark::find()->where('status <> "deleted"');
if (!($this->load($params) && $this->validate())) {
THROW AN ERROR SOMEHOW HERE
}
$query->andFilterWhere([
'status' => $this->status,
'id' => $this->id,
'reminder' => $this->reminder,
'order' => $this->order,
'update_time' => $this->update_time,
'update_by' => $this->update_by,
'create_time' => $this->create_time,
'create_by' => Yii::$app->user->id,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'url', $this->url]);
return $query->all();
}
however this will return to you all the records because ActiveDataProvider takes care of the pagination based on the query given.
Solution 2, a better solution
read the first example here http://www.yiiframework.com/doc-2.0/yii-data-activedataprovider.html . You can call ->getModels() on an ActiveDataProvider to get the actual records. No changes needed to the search function. Do whatever you want with the array.
Solution 3 and what I use all the time
Use ActiveDataProvider with a ListView. The list view allows you to create the list of records however you want, it does not have to be a table. I personally do this in many places and it works quite well. I sometimes transform arrays to an ArrayDataProvider just to use it. More about data providers here: http://www.yiiframework.com/doc-2.0/guide-output-data-providers.html