Import an excel and insert into database - laravel

How to import an excel file and add the data into the database? I have the logic in the controller (I think) but I'm unsure how to send it from the vue to the controller? I'm basing this code on another project I was working on and tutorials but I don't know how to adapt it to my project.
This is the controller store function
public function store(Request $request)
{
ini_set('max_execution_time', 300);
$users = $request->all();
try {
DB::beginTransaction();
foreach ($users as $user) {
$dbUser = $this->getUser($user['CARNET']);
Log::error($dbUser);
$dbUser->name = $user['NOMBRE'];
$dbUser->card = $user['CEDULA'];
$dbUser->scard = $user['CARNET'];
$dbUser->email = $user['CORREO'];
$dbUser->password = $user['PASSWORD'];
$this->isSet('TIPO-USUARIO', $user);
$user_type_id = $this->getUserId($user['TIPO-USUARIO']);
$dbUser->user_type_id = $user_type_id->id;
$dbUser->save();
foreach (explode(',', str_replace(' ', '', $user['CATEGORIA-USUARIO'])) as $c) {
$category = $this->getCategory($c);
$dbUser->userCategory()->save($category);
}
$dbUser->save();
}
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw new HttpException(500, 'Sucedio un error importando la información favor intentar de nuevo');
}
}
What I have in my vue
<input type="file" name="file" class="inputfile" id="fileUpload"/>
<label for="fileUpload">Select Excel</label>
<el-button
style="margin: 5px; margin-left: 20px"
type="primary"
class="mt-1"
:loading="loading"
#click="sendData()">Import
</el-button>
sendData(data) {
this.loading = true;
this.error = {};
this.$http.post(this.baseUrl, data, this.params)
.then(
() => {
this.successAction();
this.errorDis = false;
},
(res) => {
this.showErrors(res);
this.errorDis = true;
}
);
},
successAction() {
this.loading = false
},
showErrors(res) {
const [message, errors] = parseError(res);
this.error = {
message,
errors
};
this.loading = false;
this.processing = false;
},
I'm not sure how to send the actual data to the controller to be able to save it.

You could use Laravel-Excel to read the file, create an object or array and store the data on the table that you want. In the view (blade, vue, jQuery, whatever) you just must send the file as POST though a route like this:
Route::post('/importExcel', 'YourController#importExcelmethod');
In the controller you could make something like this:
public function importExcel(Request $request)
{
if($request->file('import_file')){
$path = $request->file('import_file')->getRealPath();
$data = Excel::selectSheetsByIndex(0)->load($path, function($reader) {
})->get()->toArray();
if(!empty($data) && (count($data)> 0)){
foreach ($data as $key => $value) {
DB::table('your_table')->insert(
[
"a_column" => $value[0],
"another_comun" => $value[1],
//etc
]
);
}
More info here and examples here: https://docs.laravel-excel.com/3.1/imports/
Actually there are some easier examples on how to store data to a Model from the xls like this:
public function import()
{
Excel::import(new UsersImport, 'users.xlsx');
return redirect('/')->with('success', 'All good!');
}

Related

How to get all routes within a route group?

I need to print a main menu and instead of having a database where the links/ routes are stored I thought it there would be a way to get all routes that are in a named group, but all I find is getting routes by action.
web.php
Route::group(['as' => 'main'], function () {
Route::get('/', function () {
return view('pages.start');
})->name('Home');
Route::get('/foobar', function () {
return view('pages.foobar');
})->name('Home');
Route::get('/business', function () {
return view('pages.business');
})->name('Business');
});
I was looking for something like:
$routes = getRoutesByGroup('main');
I cannot really believe that a function like that doesnt exist in current Laravel but I cant seem to find this. What am I missing?
Maybe this can solve partially in your case
function getRoutesByStarting($start = '')
{
$list = \Route::getRoutes()->getRoutesByName();
if (empty($start)) {
return $list;
}
$routes = [];
foreach ($list as $name => $route) {
if (\Illuminate\Support\Str::startsWith($name, $start)) {
$routes[$name] = $route;
}
}
return $routes;
}
usage
getRoutesByStarting('main')
More general solution
function getRoutesByGroup(array $group = [])
{
$list = \Route::getRoutes()->getRoutes();
if (empty($group)) {
return $list;
}
$routes = [];
foreach ($list as $route) {
$action = $route->getAction();
foreach ($group as $key => $value) {
if (empty($action[$key])) {
continue;
}
$actionValues = Arr::wrap($action[$key]);
$values = Arr::wrap($value);
foreach ($values as $single) {
foreach ($actionValues as $actionValue) {
if (Str::is($single, $actionValue)) {
$routes[] = $route;
} elseif($actionValue == $single) {
$routes[] = $route;
}
}
}
}
}
return $routes;
}
usage
getRoutesByGroup(['middleware' => 'api']);
getRoutesByGroup(['middleware' => ['api']]);
getRoutesByGroup(['as' => 'api']);
getRoutesByGroup(['as' => 'api*']);
getRoutesByGroup(['as' => ['api*', 'main']]);
$allRoutes = Route::getRoutes()->getRoutes(); // fetch all rotues as array
$name = 'main'; // specify your full route name
$grouped_routes = array_filter($allRoutes, function($route) use ($name) {
$action = $route->getAction(); // getting route action
if (isset($action['as'])) {
if (is_array($action['as'])) {
return in_array($name, $action['as']);
} else {
return $action['as'] == $name;
}
}
return false;
});
// output of route objects in the 'main' group
dd($grouped_routes);

On vue how to make a Edit function

Im doing my first CRUD with Vue - Laravel, i did a Add function that works fine but my Edit button is doing another Add function.
(I get the alert from updateDespesa alert("Usuário Alterado!");)
My Frontend:
async updateDespesa(despesa) {
const response = await axios
.put("api/despesas/" + despesa, {
des: this.despesa.des,
valr: this.despesa.valr,
vencc: this.despesa.vencc,
stt: this.despesa.stt,
emiss: this.despesa.emiss,
})
.then((response) => {
this.despesa.id = "";
this.despesa.valr = "";
this.despesa.stt = "";
this.despesa.vencc = "";
this.despesa.emiss = "";
this.getDespesa();
if(despesa){
alert("Usuário Alterado!");
}
})
.catch((err) => {
console.log(err);
});
},
My Backend:
public function update(Request $request, $id) {
if ($id == 0) {
$despesa = new Despesa;
$despesa->create($request->all());
}
else {
$despesa = Despesa::findOrFail($id);
$despesa->fill($request->all())->save();
}
//$despesa->update($request->all());
return response()->json('Sucess');
}
In your backend, try update this and see
public function update(Request $request, $id) {
if ($id == 0) {
$despesa = new Despesa;
$despesa->create($request->all());
}
else {
$despesa = Despesa::findOrFail($id);
$despesa->fill($request->all())->save();
}
//$despesa->update($request->all());
return response()->json('Sucess');
}
and also please check the Despesa Model has declared the input fields in protected $fillable
async updateDespesa(despesa) {
const response = await axios
.put("api/despesas/" + despesa, {
...
})
.then((response) => {
// add this line, to check only alert when id is not null
// so that it only alert when update
if(despesa){
alert("Usuário Alterado!");
}
....
})
.catch((err) => {
console.log(err);
});
},

Symfony 5 ajax post form

I need to make dynamic form in symfony 5 with ajax.
I make post request with axios on input value change on main route "/".
This route call my controller and i call dump() function for debug my request but i don't have any params on my request.
I looked in my network and my data is posted well. But I don't receive params on my request controller :/
On my view
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
cat = document.getElementById("article_category")
token = document.querySelector("#article__token");
title = document.querySelector("#article_title");
cat.addEventListener("change", function (e) {
let form = document.querySelector("form")
let data = {}
data[title.getAttribute("name")] = title.value
data[token.getAttribute("name")] = token.value
data[cat.getAttribute("name")] = cat.value
axios.post("https://127.0.0.1:8000/", data).then(res => {
str = res.data
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text/html')
console.log(doc);
}).catch(function (error) {
console.log(error);
});
})
</script>
My Controller
/**
* #Route("/", name="article")
*/
public function index(Request $request, EntityManagerInterface $em): Response
{
$article = new Article();
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
dump($request);
}
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($article);
$em->flush();
}
return $this->render('article/index.html.twig', [
"form" => $form->createView(),
]);
}
FormType
$builder
->add('title')
->add('category')
->add('Submit', SubmitType::class);
$builder->get('category')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
if ($form->getData()->getName() == "Cat 0") {
$form->getParent()->add('tag', EntityType::class, [
'class' => Tag::class,
]);
}
}
);

How to organize data to send a post request to a API? laravel + vue-cli project

i'm writing a code using laravel as backend and vue-cli as frontend.
i've got a problem with the data to send to an API laravel restful controller. I get back as answer the err 500.
That's my saveEvent code:
saveEvent() {
const staff = this.$store.getters.get_selected_staff.map(
raw_staff => {
return {
...raw_staff,
icon: "mdi-drama-masks" ? "actor" : "technician",
percent:
raw_staff.percent == "full"
? 1
: eval(raw_staff.percent),
allowance: parseInt(raw_staff.allowance),
daily: parseInt(raw_staff.daily)
};
}
);
const show = {
...this.$store.getters.get_tournee_show_detail
};
this.$http
.post(
"http://localhost:8080/api/tourneeDetail",
`show=${JSON.stringify(show)}&staff=${JSON.stringify(
staff
)}`
)
.then(response => {
this.closeEvent();
})
.catch(error => {
console.log("errore nella registrazione", error);
});
// );
}
The datas goest straight to the controller and get manages in this way:
public function store(Request $request)
{
//
dd($request->all());
$tournee = new TourneeDetail;
$show = json_decode($request->show, true);
$staff = json_decode($request->staff, true);
foreach ($show as $detail => $value){
if($detail == "stage_id"){
$tournee->stage_id = $value['id'];
}
else{
$tournee[$detail] = $value;
}
}
$tournee->save();
foreach ($staff as $row){
$staff = new Staff;
foreach ($row as $detail => $value){
if ($detail!="icon" && $detail!="names" ){
$staff[$detail] = $value;
}
}
$staff->type = $row["icon"];
$staff->tournee_detail_id = $tournee->id;
$staff->save();
foreach ($row["names"] as $id){
$staff_person = new StaffPerson;
$staff_person->person_id = $id;
$staff_person->staff_id = $staff->id;
$staff_person->save();
}
}
return $tournee;
}
The problem is that i get the 500 error on the 1rst foreach. I put a dd to check the $request->all() and i noticed that the payload sent is correct but the preview is an empty array!
I dunno how to fix this problem..any help would be appreciated!
Thank you
Valerio

How to parse data on the backend

I am using Angular2 for my frontend and laravel for my back end and I'm having trouble saving the data to the database
Each of the keys in the Order[] (ex prodName, prodDesc) are the same as the column names in the database so I was trying to loop the request and save the data but its not working
public function Order(Request $request) {
$input = $request->all();
$order = new Order;
foreach ($input as $key => $value) {
if (array_key_exists($key, $input) && !empty($value)) {
$order->$key = $value;
}
}
}
if($order->save()) {
return response()->json(['order' => $order], 201);
}
order.interface.ts
export interface Order {
prodName: string;
prodDesc: string;
}
Adding the item to the order
addToOrder.component.ts
orders = [] as Order[];
saveItem(): void {
this.orders.push({prodName: this.prodName, prodDesc: this.prodDesc});
this.dataService.save(this.orders).then(() => {
this.navCtrl.pop(Search);
});
}
How each item is stored in storage
order.storage.ts
save(data : Order[]): Promise<any> {
return this.getData().then((products: any[]) => {
if (products) {
products = products.concat(data);
return this.storage.set('products', products);
}
return this.storage.set('products', data);
});
}
How I retrieve the order from storage
order.component.ts
private order = [] as Order[];
constructor(public dataService: OrderStorage, public OrderService: OrderService) {
this.dataService.getData().then((products) => {
if (products) {
this.order = products;
}
});
}
onSubmit() {
this.OrderService.submit(this.order)
.subscribe();
}
Posting the data to the back end
order.service.ts
submit(order: Order[]): Observable<any> {
return this.http.post(localapi.app, order)
.map(
(response: Response) => {});
}
Structure of the order data being sent
Retrieving the data on the backend
public function Order(Request $request) {
$input = $request->all();
var_dump($input);
}
the var_dump output
It's actually foreach ($input as $key => $arr), then you can use your loop:
foreach ($input as $arr) {
foreach ($arr as $key => $value) {
if (array_key_exists($key, $arr) && !empty($value)) {
$order->$key = $value;
}
}
}
The first set of elements you will encounter in your loop are arrays, then you can loop the property off of your array.

Resources