I have this in the command but not saving the database.
$client = new Client(HttpClient::create(['timeout' => 60]));
$crawler = $client->request('GET', 'https://www.bbc.com/news/');
$model = new Scraper();
$crawler->filter('.gs-c-promo-heading')->each(function ($node) {
$model->title = $node->text();
});
$crawler->filter('.gs-c-promo-summary')->each(function ($node) {
$model->text = $node->text();
});
$crawler->filter('.gs-c-timestamp')->each(function ($node) {
$model->time = $node->text();
});
$crawler->filter('.gs-c-section-link')->each(function ($node) {
$model->country = $node->text();
});
$model->save();
$this->info('done success');
Giving this type of error
$ php artisan scraper:start
ErrorException
Creating default object from empty value
at E:\wamp64\www\Laravel7Projects\system\system\app\Console\Commands\ScrapCommand.php:49
45| $crawler = $client->request('GET', 'https://www.bbc.com/news/');
46|
47| $crawler->filter('.gs-c-promo-heading')->each(function ($node) {
48|
> 49| $model->title = $node->text();
51| });
52| $crawler->filter('.gs-c-promo-summary')->each(function ($node) {
53|
1 E:\wamp64\www\Laravel7Projects\system\system\app\Console\Commands\ScrapCommand.php:49
Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Creating default object from empty value", "E:\wamp64\www\Laravel
7Projects\system\system\app\Console\Commands\ScrapCommand.php", [Object(Symfony\Component\DomCrawler\Crawler), Object(stdClass)])
2 E:\wamp64\www\Laravel7Projects\system\system\vendor\symfony\dom-crawler\Crawler.php:352
App\Console\Commands\ScrapCommand::App\Console\Commands\{closure}(Object(Symfony\Component\DomCrawler\Crawler))
but with this mthod is working which is no need because I want to save all attributes in one new class
$crawler->filter('.gs-c-promo-heading')->each(function ($node) {
$model = new Scraper();
$model->title = $node->text();
$model->save();
});
I want to save every attribute in the database but getting error
With this logic only saving first row where as i want to save all loop in the database
$client = new Client(HttpClient::create(['timeout' => 60]));
$crawler = $client->request('GET', 'https://www.bbc.com/news/');
$model = new Scraper();
$crawler->filter('.gs-c-promo-heading')->each(function ($node) use ($model) {
$model->title = $node->text();
});
$model->save();
Edit: Only titles are saving in the database whereas others not saving with this method because we are looping only titles in foreach
And map is not working whereas each in working you can check below code
$titles = $crawler->filter('.gs-c-promo-heading')->each(function($node) {
return $node->text();
});
$texts = $crawler->filter('.gs-c-promo-summary')->each(function($node) {
return $node->text();
});
$times = $crawler->filter('.gs-c-timestamp')->each(function($node) {
return $node->text();
});
$countries = $crawler->filter('.gs-c-section-link')->each(function($node) {
return $node->text();
});
$dataArray = [];
foreach ($titles as $key => $item) {
$newModelData = [
'title' => $titles[$key],
'text' => $texts[$key],
'time' => $times[$key],
'country' => $countries[$key]
];
$dataArray[] = $newModelData;
}
Scraper::insert($dataArray);
When you are using each() you don't have access to $model variable (outside of the scope).
You should try use() to introduce $model variable inside of local scope of an anonymous function
$crawler->filter('.gs-c-promo-heading')->each(function ($node) use($model) {
$model->title = $node->text();
});
Edit: If you want to save multiple items at the same time you could pluck necessary values and then create arrays of data according to your model attributes.
$titles = $crawler->filter('.gs-c-promo-heading')->map(function($node) {
return $node->text();
});
$texts = $crawler->filter('.gs-c-promo-heading')->map(function($node) {
return $node->text();
});
// same for times, countries
$dataArray = [];
foreach ($titles as $key => $item) {
$newModelData = [
'title' => $titles[$key],
'text' => $texts[$key],
'time' => $times[$key],
'country' => $countries[$key]
];
$dataArray[] = $newModelData;
}
Model::createMany($dataArray);
Related
I've got object variables that I want to update inside promises guzzle with closure:
foreach ($urls as $i => $url) {
$this->facebook[$url] = 0;
$this->googlePlus[$url] = 0;
$this->pinterest[$url] = 0;
$this->twitter[$url] = 0;
$this->metaResults[$url] = [
'url' => false,
'title' => false,
'desc' => false,
'h1' => false,
'word_count' => 0,
'keyword_count' => 0
];
$that = $this;
$promise = $client->getAsync($url)->then(function ($content) {
return $content->getBody()->getContents();
})->then(function($html) use (&$url, &$that) {
$that->metaResults[$url] = $this->parseMeta($html);
});
$promeses['meta'][$url] = $promise;
}
$responses = Promise\Utils::settle($promises)->wait();
The problem as you can see above $that->metaResults[$url] = $this->parseMeta($html); this is never saved on that object var. Is there a way to do this?
It seems to me like there are few errors. If you want to use $url and $that shouldn't you pass it in to callbacks registered with the promises's then method for first one. Also I think that $this will not be accessible inside the callback registered with the then(). Though you will need to check for $this.
$promise = $client->getAsync($url)
->then(function (ResponseInterface $content) use ($url, $that) {
return $content->getBody()->getContents();
})
->then(function($html) use ($url, $that) {
$that->metaResults[$url] = $this->parseMeta($html);
});
$promeses['meta'][$url] = $promise;
reference
vue function:
sendData() {
this.isLoading = true;
const postData = {
data: this.items,
};
var self = this;
axios.post(this.postUrl, postData).then(function (response) {
console.log(response.data);
self.isLoading = false;
});
this.items = [];
},
Laravel controller:
public function store(request $request)
{
foreach ($request->data as $data) {
$serie = [];
$serie = ['imei' => $data['serie']];
$imei = new Imei([
'imei' => $data['serie'],
'status_id' => 1,
'sucursal_id' => $data['sucursal'],
'equipo_id' => $data['equipo']
]);
$validator = Validator::make($serie, [
'imei' => 'unique:imeis,imei|digits:15',
]);
if ($validator->fails()) {
// Here I need to build the response of every imei with its validation error
} else {
$imei->save();
}
}
return >Here I want to return the errors back to vue
}
my vue app sends to laravel trough axios an array of objects that looks like this [{imei:xxxx,sucursal_id...},{imei:xxxx,sucursal_id...}] I need to validate imei is unique and save it, and if error return errors in the same way [{imei:xxxx,errorMsg: 'already exist in DB'}]. but I can't find the proper way to do it.
Basically you want to customize your errorbag right ? try this one out. Add this inside your fail condition. Let me know if it works.
$err = [{imei:xxxx,errorMsg: 'already exist in DB'}];
foreach ($validator->errors()->toArray() as $error) {
foreach($error as $sub_error) {
array_push($err, $sub_error);
}
}
return ['errors'=>$err];
I'm trying to save the passed course_id into lesson form in a DRY format.
I've tried saving each variable individually and it worked, however when I try to DRY up the code it is not working. Here is the code That I've tried.
public function store(StoreLessonsRequest $request)
{
if (! Gate::allows('lesson_create')) {
return abort(401);
}
$request = $this->saveFiles($request);
$lesson = Lesson::create($request->all() +
$lesson->course_id = session()->get('id') +
+ ['position' => Lesson::where('course_id', $request->course_id)->max('position') + 1]);
foreach ($request->input('lesson_materials_id', []) as $index => $id) {
$model = config('medialibrary.media_model');
$file = $model::find($id);
$file->model_id = $lesson->id;
$file->save();
}
return redirect()->route('admin.exams.create', ['course_id' => $request->course_id]);
}
I expected the course_id to save, but is giving me an error of Unsupported operand types.
Here is how I finally solved it. First I've declared the variable then I've passed it through.
public function store(StoreLessonsRequest $request)
{
if (! Gate::allows('lesson_create')) {
return abort(401);
}
$request = $this->saveFiles($request);
$seesion = session()->get('id');
$lesson = Lesson::create($request->all()
+ ['position' => Lesson::where('course_id', $request->course_id)->max('position') + 1] + ['course_id' => $seesion] );
foreach ($request->input('lesson_materials_id', []) as $index => $id) {
$model = config('medialibrary.media_model');
$file = $model::find($id);
$file->model_id = $lesson->id;
$file->save();
}
I am trying to increase the speed of my queries in Laravel 5.7 and I have the call down to ~2.5 seconds. I am trying to figure out more ways to make it faster and if I could get some help I'd greatly appreciate it.
Thanks
How my data is structured:
Function(Controller):
public function getUserDataTmp(Request $request) {
$input = file_get_contents("php://input");
$request = json_decode($input);
if ($this->authTokenAccess($request) == true) {
$bottomWords = bottom_exterior_word::select('word','sentence','sequence','id','group_id')->where('user_id','=', $request->id)->get();
$emergencyWords = left_exterior_word::select('word','sentence','sequence','id')->where('user_id','=', $request->id)->get();
foreach($bottomWords as $tmp => $key) {
$group_id = $key->group_id;
$bottomWords->user_id = $request->id;
$bottomWords[$tmp]->words = $key->getMainWords($group_id, $request->id);
}
foreach($emergencyWords as $key => $word) {
$emergencyWords[$key]->image = imageModel::select('base64','id')->where('emergency_id','=', $word->id)->first();
}
$data = [
'data' => [
'return' => 'success',
'code' => 'VEDC001',
'response' => 'Successfully Gathered Words',
'main_categories' => $bottomWords,
'emergency_words' => $emergencyWords
]
];
return(json_encode($data));
}
}
getMainWords Function(bottom_exterior_word model):
public function getMainWords($group_id, $id)
{
// return("TEST");
$words = \App\main_word::select('id','group_id','sentence','sequence','word')->where('group_id','=', $group_id)->where('user_id','=', $id)->get();
foreach ($words as $key => $word) {
$words[$key]->image = Image::select('base64','id')->where('word_id','=', $word->id)->first();
}
return $words;
}
Start by refactoring so that you dont query inside a foreach loop
foreach($bottomWords as $tmp => $key) {
$group_id = $key->group_id;
$bottomWords->user_id = $request->id;
$bottomWords[$tmp]->words = $key->getMainWords($group_id, $request->id);
}
I would change the getMainWords function to accepts an array of group id's and use the whereIn clause:
The whereIn method verifies that a given column's value is contained
within the given array:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
Same treatment for this loop.
foreach($emergencyWords as $key => $word) {
$emergencyWords[$key]->image = imageModel::select('base64','id')->where('emergency_id','=', $word->id)->first();
}
In general minimizing the NUMBER of queries will improve response time.
Old post, would just like to update it though. Since I have first posted this, I have learned a lot more about Laravel and am a lot more experienced with it.
Here is my new function and solution:
Controller:
public function data(Request $request)
{
return response()->success(
[
'emergencywords' => EmergencyWord::with('image')->whereUserId($request->user()->id)->get(),
'categorywords' => CategoryWord::with(['image','words.image'])->whereUserId($request->user()->id)->get(),
]
);
}
Category Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}
public function words()
{
return $this->hasMany('App\MainWord','category_words_id','sequence');
}
Emergency Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}
Main Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}
I am new in Zend Framework. I am trying to display data from database using JSON. And I encoded the data and passed it to JQuery. But cannot retrieve value from database. Data displayed as "undefined". My controller function is as follows:
public function displayAction()
{
$data1 = array();
$request = $this->getRequest();
$response = $this->getResponse();
if ($request->isPost()) {
$response->setContent(\Zend\Json\Json::encode(array('data' => $this-> getStickyNotesTable() -> fetchAll())));
}
return $response;
}
My FetchAll() is:
public function fetchAll() {
$resultSet = $this->select(function (Select $select) {
$select->order('created ASC');
});
$entities = array();
foreach ($resultSet as $row) {
$entity = new Entity\StickyNote();
$entity->setId($row->id)
->setNote($row->note)
->setCreated($row->created);
$entities[] = $entity;
}
return $entities;
}
JQuery function :
function getUserList(element) {
$('#indicator').show();
$.post('stickynotes/display',
function(data, textStatus) {
renderUserList(data);
$('#indicator').hide();
},
"json"
);
}
function renderUserList(jsonData) {
var table = '<table width="600" cellpadding="5" class="table table-hover table-bordered"><thead><tr><th scope="col">Note</th></tr></thead><tbody>';
$.each(jsonData, function(index, data){
table += '<tr>';
table += '<td class="edit" field="note" user_id="'+data.id+'">'+data.note+'</td>';
table += '<td><i class="icon-remove icon-white"></i></td>';
table += '</tr>';
});
table += '</tbody></table>';
$('div#content').html(table);
}
I tested it using Firebug. It shows
{"data":[{},{},{},{},{},{},{},{},{},{},{},{},{}]}
as Response.
Anyone please help me. Thanks.
The issue is with your fetchAll method. Try with this updated version:
public function fetchAll() {
$resultSet = $this->select(function (Select $select) {
$select->order('created ASC');
});
$entities = array();
foreach ($resultSet as $row) {
$entity = array(
"id" => $row->id,
"note" => $row->note,
"created" => $row->created
);
$entities[] = $entity;
}
return $entities;
}
You'll need to configure your module.config.php and add a strategy within your template_map add.
'strategies' => array(
'ViewJsonStrategy',
),
to return a jsonModel.
If you want to work with a jsonModel within your controller you'll need to call it like so:
$json = new JsonModel(array(
'param' => 'foobar',
'success' => true,
));
return $json;